001: /*****************************************************************************
002: * Java Plug-in Framework (JPF)
003: * Copyright (C) 2004-2007 Dmitry Olshansky
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: *****************************************************************************/package org.java.plugin.tools.ant;
019:
020: import java.io.BufferedReader;
021: import java.io.File;
022: import java.io.FileInputStream;
023: import java.io.IOException;
024: import java.io.InputStreamReader;
025: import java.net.MalformedURLException;
026: import java.net.URL;
027: import java.util.HashMap;
028: import java.util.HashSet;
029: import java.util.LinkedList;
030: import java.util.List;
031: import java.util.Map;
032: import java.util.Set;
033: import java.util.Map.Entry;
034:
035: import org.apache.tools.ant.BuildException;
036: import org.apache.tools.ant.Project;
037: import org.apache.tools.ant.taskdefs.MatchingTask;
038: import org.apache.tools.ant.types.FileSet;
039: import org.apache.tools.ant.util.FileUtils;
040: import org.java.plugin.ObjectFactory;
041: import org.java.plugin.PathResolver;
042: import org.java.plugin.registry.Identity;
043: import org.java.plugin.registry.ManifestInfo;
044: import org.java.plugin.registry.ManifestProcessingException;
045: import org.java.plugin.registry.PluginRegistry;
046: import org.java.plugin.util.IoUtil;
047:
048: /**
049: * Base class for some JPF related ant tasks.
050: * @version $Id: BaseJpfTask.java,v 1.8 2007/03/03 17:16:26 ddimon Exp $
051: */
052: public abstract class BaseJpfTask extends MatchingTask {
053: private static final FileUtils fileUtils = FileUtils.newFileUtils();
054:
055: private final LinkedList<FileSet> fileSets = new LinkedList<FileSet>();
056: private File baseDir;
057: private boolean verbose;
058: private PluginRegistry registry;
059: private PathResolver pathResolver;
060: private Set<String> whiteList;
061: private Set<String> blackList;
062:
063: /**
064: * @param set the set of files to be registered as manifests
065: */
066: public void addFileset(final FileSet set) {
067: fileSets.add(set);
068: }
069:
070: /**
071: * @param aBaseDir base directory for manifest files
072: */
073: public final void setBaseDir(final File aBaseDir) {
074: this .baseDir = aBaseDir;
075: }
076:
077: /**
078: * @param aVerbose <code>true</code> if detailed integrity check report
079: * required
080: */
081: public final void setVerbose(final boolean aVerbose) {
082: this .verbose = aVerbose;
083: }
084:
085: /**
086: * @param file while list file
087: * @throws IOException if list reading failed
088: */
089: public final void setWhiteList(final File file) throws IOException {
090: whiteList = loadList(file);
091: }
092:
093: /**
094: * @param file black list file
095: * @throws IOException if list reading failed
096: */
097: public final void setBlackList(final File file) throws IOException {
098: blackList = loadList(file);
099: }
100:
101: protected Set<String> loadList(final File file) throws IOException {
102: if (file == null) {
103: return null;
104: }
105: Set<String> result = new HashSet<String>();
106: BufferedReader reader = new BufferedReader(
107: new InputStreamReader(new FileInputStream(file),
108: "UTF-8")); //$NON-NLS-1$
109: try {
110: String line;
111: while ((line = reader.readLine()) != null) {
112: line = line.trim();
113: if (line.length() > 0) {
114: result.add(line);
115: }
116: }
117: } finally {
118: reader.close();
119: }
120: return result;
121: }
122:
123: protected final boolean getVerbose() {
124: return verbose;
125: }
126:
127: protected final PathResolver getPathResolver() {
128: return pathResolver;
129: }
130:
131: protected final PluginRegistry getRegistry() {
132: return registry;
133: }
134:
135: protected Set<String> getWhiteList() {
136: return whiteList;
137: }
138:
139: protected Set<String> getBlackList() {
140: return blackList;
141: }
142:
143: protected final void initRegistry(final boolean usePathResolver) {
144: if (baseDir != null) {
145: if (!baseDir.isDirectory()) {
146: throw new BuildException("basedir " + baseDir //$NON-NLS-1$
147: + " does not exist!", getLocation()); //$NON-NLS-1$
148: }
149: } else {
150: baseDir = getProject().getBaseDir();
151: }
152: ObjectFactory objectFactory = ObjectFactory.newInstance();
153: registry = objectFactory.createRegistry();
154: File[] manifestFiles = getIncludedFiles();
155: List<URL> manifestUrls = new LinkedList<URL>();
156: final Map<String, URL> foldersMap = new HashMap<String, URL>();
157: for (int i = 0; i < manifestFiles.length; i++) {
158: File manifestFile = manifestFiles[i];
159: try {
160: //manifestUrls[i] = IoUtil.file2url(manifestFile);
161: URL manifestUrl = getManifestURL(manifestFile);
162: if (manifestUrl == null) {
163: if (verbose) {
164: log("Skipped file: " + manifestFile); //$NON-NLS-1$
165: }
166: continue;
167: }
168: try {
169: if (!isManifestAccepted(manifestUrl)) {
170: if (verbose) {
171: log("Skipped URL: " + manifestUrl); //$NON-NLS-1$
172: }
173: continue;
174: }
175: } catch (ManifestProcessingException mpe) {
176: throw new BuildException(
177: "can't read manifest from URL " //$NON-NLS-1$
178: + manifestUrl, mpe, getLocation());
179: }
180: manifestUrls.add(manifestUrl);
181: if (verbose) {
182: log("Added URL: " + manifestUrl); //$NON-NLS-1$
183: }
184: if (usePathResolver) {
185: /*foldersMap.put(manifestUrls[i],
186: IoUtil.file2url(manifestFile.getParentFile()));*/
187: if ("jar".equals(manifestUrl.getProtocol())) { //$NON-NLS-1$
188: foldersMap.put(manifestUrl.toExternalForm(),
189: IoUtil.file2url(manifestFile));
190: } else {
191: foldersMap.put(manifestUrl.toExternalForm(),
192: IoUtil.file2url(manifestFile
193: .getParentFile()));
194: }
195: }
196: } catch (MalformedURLException mue) {
197: throw new BuildException("can't create URL for file " //$NON-NLS-1$
198: + manifestFile, mue, getLocation());
199: }
200: }
201: final Map<String, Identity> processedPlugins;
202: try {
203: processedPlugins = registry.register(manifestUrls
204: .toArray(new URL[manifestUrls.size()]));
205: } catch (Exception e) {
206: throw new BuildException(
207: "can't register URLs", e, getLocation()); //$NON-NLS-1$
208: }
209: log(
210: "Registry initialized, registered manifests: " //$NON-NLS-1$
211: + processedPlugins.size()
212: + " of " + manifestUrls.size(), //$NON-NLS-1$
213: (processedPlugins.size() != manifestUrls.size()) ? Project.MSG_WARN
214: : Project.MSG_INFO);
215: if (usePathResolver) {
216: pathResolver = objectFactory.createPathResolver();
217: for (Entry<String, Identity> entry : processedPlugins
218: .entrySet()) {
219: pathResolver.registerContext(entry.getValue(),
220: foldersMap.get(entry.getKey()));
221: }
222: if (verbose) {
223: log("Path resolver initialized"); //$NON-NLS-1$
224: }
225: }
226: }
227:
228: protected File[] getIncludedFiles() {
229: Set<File> result = new HashSet<File>();
230: for (FileSet fs : fileSets) {
231: for (String file : fs.getDirectoryScanner(getProject())
232: .getIncludedFiles()) {
233: if (file != null) {
234: result.add(fileUtils.resolveFile(fs
235: .getDir(getProject()), file));
236: }
237: }
238: }
239: if (fileSets.isEmpty()) {
240: for (String file : getDirectoryScanner(baseDir)
241: .getIncludedFiles()) {
242: if (file != null) {
243: result.add(fileUtils.resolveFile(baseDir, file));
244: }
245: }
246: }
247: return result.toArray(new File[result.size()]);
248: }
249:
250: protected URL getManifestURL(final File file)
251: throws MalformedURLException {
252: if (file.getName().endsWith(".jar") || file.getName().endsWith(".zip")) { //$NON-NLS-1$ //$NON-NLS-2$
253: URL url = new URL(
254: "jar:" + IoUtil.file2url(file).toExternalForm() //$NON-NLS-1$
255: + "!/plugin.xml"); //$NON-NLS-1$
256: if (IoUtil.isResourceExists(url)) {
257: return url;
258: }
259: url = new URL(
260: "jar:" + IoUtil.file2url(file).toExternalForm() //$NON-NLS-1$
261: + "!/plugin-fragment.xml"); //$NON-NLS-1$
262: if (IoUtil.isResourceExists(url)) {
263: return url;
264: }
265: url = new URL(
266: "jar:" + IoUtil.file2url(file).toExternalForm() //$NON-NLS-1$
267: + "!/META-INF/plugin.xml"); //$NON-NLS-1$
268: if (IoUtil.isResourceExists(url)) {
269: return url;
270: }
271: url = new URL(
272: "jar:" + IoUtil.file2url(file).toExternalForm() //$NON-NLS-1$
273: + "!/META-INF/plugin-fragment.xml"); //$NON-NLS-1$
274: if (IoUtil.isResourceExists(url)) {
275: return url;
276: }
277: return null;
278: }
279: return IoUtil.file2url(file);
280: }
281:
282: protected boolean isManifestAccepted(final URL manifestUrl)
283: throws ManifestProcessingException {
284: if ((whiteList == null) && (blackList == null)) {
285: return true;
286: }
287: ManifestInfo manifestInfo = registry
288: .readManifestInfo(manifestUrl);
289: if (whiteList != null) {
290: if (isPluginInList(manifestInfo, whiteList)) {
291: return true;
292: }
293: }
294: if ((blackList != null)
295: && isPluginInList(manifestInfo, blackList)) {
296: return false;
297: }
298: return true;
299: }
300:
301: private boolean isPluginInList(final ManifestInfo manifestInfo,
302: final Set<String> list) {
303: if (list.contains(manifestInfo.getId())) {
304: return true;
305: }
306: return list.contains(registry.makeUniqueId(
307: manifestInfo.getId(), manifestInfo.getVersion()));
308: }
309: }
|