001/*
002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     bstefanescu
018 *
019 * $Id$
020 */
021
022package org.nuxeo.osgi.application;
023
024import java.io.BufferedReader;
025import java.io.BufferedWriter;
026import java.io.File;
027import java.io.FileReader;
028import java.io.FileWriter;
029import java.io.IOException;
030import java.util.ArrayList;
031import java.util.List;
032
033import org.nuxeo.osgi.BundleFile;
034import org.nuxeo.osgi.DirectoryBundleFile;
035import org.nuxeo.osgi.JarBundleFile;
036
037/**
038 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
039 */
040public class ClassPath implements ClassPathScanner.Callback {
041
042    protected final List<BundleFile> bundles;
043
044    protected final List<BundleFile> jars;
045
046    protected final List<BundleFile> nestedJars;
047
048    protected final SharedClassLoader loader;
049
050    protected final File nestedJARsDir;
051
052    public ClassPath(SharedClassLoader loader, File nestedJARsDir) {
053        bundles = new ArrayList<>();
054        jars = new ArrayList<>();
055        nestedJars = new ArrayList<>();
056        this.loader = loader;
057        this.nestedJARsDir = nestedJARsDir;
058        nestedJARsDir.mkdirs();
059    }
060
061    public List<BundleFile> getBundles() {
062        return bundles;
063    }
064
065    public List<BundleFile> getJars() {
066        return jars;
067    }
068
069    public List<BundleFile> getNestedJars() {
070        return nestedJars;
071    }
072
073    public void scan(List<File> files, boolean scanForNestedJARs, String[] blacklist) {
074        new ClassPathScanner(this, scanForNestedJARs, blacklist).scan(files);
075    }
076
077    @Override
078    public File handleBundle(BundleFile bf) {
079        bundles.add(bf);
080        loader.addURL(bf.getURL());
081        return nestedJARsDir;
082    }
083
084    @Override
085    public File handleJar(BundleFile bf) {
086        jars.add(bf);
087        loader.addURL(bf.getURL());
088        return nestedJARsDir;
089    }
090
091    @Override
092    public void handleNestedJar(BundleFile bf) {
093        nestedJars.add(bf);
094        loader.addURL(bf.getURL());
095    }
096
097    public void store(File file) throws IOException {
098        BufferedWriter writer = null;
099        try {
100            writer = new BufferedWriter(new FileWriter(file));
101            for (BundleFile bf : bundles) {
102                writer.append(bf.getFile().getAbsolutePath());
103                writer.newLine();
104            }
105            writer.append("#");
106            writer.newLine();
107            for (BundleFile bf : jars) {
108                writer.append(bf.getFile().getAbsolutePath());
109                writer.newLine();
110            }
111            writer.append("#");
112            writer.newLine();
113            for (BundleFile bf : nestedJars) {
114                writer.append(bf.getFile().getAbsolutePath());
115                writer.newLine();
116            }
117        } finally {
118            if (writer != null) {
119                writer.close();
120            }
121        }
122    }
123
124    public void restore(File file) throws IOException {
125        BufferedReader reader = null;
126        try {
127            reader = new BufferedReader(new FileReader(file));
128            List<BundleFile> list = bundles;
129            String line = null;
130            while (true) {
131                line = reader.readLine();
132                if (line == null) {
133                    break;
134                }
135                if (line.startsWith("#")) {
136                    if (list == bundles) {
137                        list = jars;
138                    } else if (list == jars) {
139                        list = nestedJars;
140                    }
141                    continue;
142                }
143                BundleFile bf = null;
144                File f = new File(line.trim());
145                if (f.isDirectory()) {
146                    bf = new DirectoryBundleFile(f);
147                } else {
148                    bf = new JarBundleFile(f);
149                }
150                loader.addURL(bf.getURL());
151                list.add(bf);
152            }
153        } finally {
154            if (reader != null) {
155                reader.close();
156            }
157        }
158    }
159
160}