/* * Copyright 2004-2012 the Seasar Foundation and the Others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ package org.seasar.mayaa.impl.builder.library.scanner; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarInputStream; import org.seasar.mayaa.builder.library.scanner.SourceScanner; import org.seasar.mayaa.impl.ParameterAwareImpl; import org.seasar.mayaa.impl.source.ClassLoaderSourceDescriptor; import org.seasar.mayaa.impl.util.IOUtil; import org.seasar.mayaa.impl.util.StringUtil; import org.seasar.mayaa.impl.util.collection.NullIterator; import org.seasar.mayaa.source.SourceDescriptor; /** * @author Taro Kato (Gluegent, Inc.) */ public class JarSourceScanner extends ParameterAwareImpl implements SourceScanner { private static final long serialVersionUID = 6023587474701789138L; private String _root; private SourceDescriptor _descriptor; private Set _folderFilters = new HashSet(); private Set _ignores = new HashSet(); private Set _extensions = new HashSet(); public Iterator scan() { if (_descriptor == null) { return NullIterator.getInstance(); } Set aliases = new HashSet(); scanSource(_descriptor, aliases); return new AliasToSourceIterator(aliases.iterator()); } protected String getJarName(String systemID) { if (StringUtil.hasValue(systemID)) { int pos = systemID.lastIndexOf("/"); if (pos != -1) { return systemID.substring(pos + 1); } return systemID; } return null; } protected void scanSource(SourceDescriptor source, Set aliases) { if (source == null || source.exists() == false) { throw new IllegalArgumentException(); } String jarName = getJarName(source.getSystemID()); if (StringUtil.hasValue(jarName)) { String jarPath = ((_root != null) ? _root : "") + source.getSystemID(); Date timestamp = source.getTimestamp(); InputStream stream = null; JarInputStream jar = null; try { stream = source.getInputStream(); jar = new JarInputStream(stream); addAliases(jar, jarPath, timestamp, aliases); } catch (IOException e) { throw new RuntimeException(e); } finally { if (jar != null) { IOUtil.close(jar); } else { IOUtil.close(stream); } } } } protected void addAliases( JarInputStream jar, String jarPath, Date timestamp, Set aliases) throws IOException { JarEntry entry; while ((entry = jar.getNextJarEntry()) != null) { String entryName = entry.getName(); if (nameStartsWith(entryName) && extensionEndsWith(entryName)) { aliases.add(new SourceAlias(jarPath, entryName, timestamp)); } } } protected boolean nameStartsWith(String entryName) { if (_folderFilters.size() > 0) { boolean ok = false; for (Iterator it = _folderFilters.iterator(); it.hasNext(); ) { String filter = (String) it.next(); if (entryName.startsWith(filter)) { ok = true; } } if (!ok) { return false; } } if (_ignores.size() > 0) { for (Iterator it = _ignores.iterator(); it.hasNext(); ) { String filter = (String) it.next(); if (entryName.startsWith(filter)) { return false; } } } return true; } protected boolean extensionEndsWith(String entryName) { if (_extensions.size() == 0) { return true; // all } for (Iterator it = _extensions.iterator(); it.hasNext(); ) { String filter = (String) it.next(); if (entryName.endsWith(filter)) { return true; } } return false; } public void setDescriptor(SourceDescriptor descriptor) { _descriptor = descriptor; } protected String getFileName(String path) { int separatorIndex = path.lastIndexOf('/'); if (separatorIndex > 0) { path = path.substring(separatorIndex+1); } else if (File.separatorChar != '/') { separatorIndex = path.lastIndexOf(File.separatorChar); if (separatorIndex > 0) { path = path.substring(separatorIndex+1); } } return path; } // Parameterizable implements ------------------------------------ public void setParameter(String name, String value) { if ("root".equals(name)) { _root = value; } else if ("folder".equals(name)) { _folderFilters.add(value); } else if ("ignore".equals(name)) { _ignores.add(value); } else if ("extension".equals(name)) { _extensions.add(value); } super.setParameter(name, value); } // suppport class ----------------------------------------------- protected static class AliasToSourceIterator implements Iterator { private Iterator _it; public AliasToSourceIterator(Iterator it) { if (it == null) { throw new IllegalArgumentException(); } _it = it; } public boolean hasNext() { return _it.hasNext(); } public Object next() { SourceAlias alias = (SourceAlias) _it.next(); ClassLoaderSourceDescriptor source = new ClassLoaderSourceDescriptor(); source.setSystemID(alias.getSystemID()); source.setParameter(SourceAlias.ALIAS, alias.getAlias()); source.setTimestamp(alias.getTimestamp()); return source; } public void remove() { throw new UnsupportedOperationException(); } } }