- /*
- * Copyright 2003-2004 The Apache Software Foundation
- *
- * 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.apache.commons.attributes.compiler;
-
- import java.io.BufferedInputStream;
- import java.io.BufferedOutputStream;
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.InputStream;
- import java.io.PrintWriter;
- import java.io.PrintStream;
- import java.net.URL;
- import java.net.URLClassLoader;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.Enumeration;
- import java.util.HashMap;
- import java.util.HashSet;
- import java.util.Iterator;
- import java.util.List;
- import java.util.jar.JarFile;
- import java.util.jar.JarEntry;
- import java.util.jar.JarOutputStream;
-
- import org.apache.commons.attributes.AttributeRepositoryClass;
- import org.apache.commons.attributes.Attributes;
- import org.apache.commons.attributes.AttributeUtil;
- import org.apache.commons.attributes.Indexed;
- import org.apache.tools.ant.AntClassLoader;
- import org.apache.tools.ant.BuildException;
- import org.apache.tools.ant.Task;
- import org.apache.tools.ant.types.FileSet;
- import org.apache.tools.ant.types.Path;
-
- /**
- * Ant task to compile attribute indexes. Usage:
- *
- * <pre><code>
- * <taskdef resource="org/apache/commons/attributes/anttasks.properties"/>
- *
- * <attribute-indexer jarFile="myclasses.jar">
- * <classpath>
- * ...
- * </classpath>
- * </attribute-indexer>
- * </code></pre>
- *
- * The task will inspect the classes in the given jar and add a <tt>META-INF/attrs.index</tt>
- * file to it, which contains the index information. The classpath element is required and
- * must contain all dependencies for the attributes used.
- */
- public class AttributeIndexer extends Task {
-
- private File jarFile;
- private List classes = new ArrayList ();
- private Path classPath;
- private File baseName;
- private boolean inMaven = false;
-
- private final static String INDEX_FILENAME = "META-INF/attrs.index";
-
- public AttributeIndexer () {
- }
-
- public void setJarfile (File jarFile) {
- this.jarFile = jarFile;
- }
-
- public void setBaseName (File baseName) {
- inMaven = true;
- this.baseName = baseName;
- }
-
- public Path createClasspath () {
- this.classPath = new Path(project);
- return classPath;
- }
-
- private static final String SUFFIX = "$__attributeRepository.class";
-
- protected void copyEntry (JarFile jar, JarEntry entry, JarOutputStream outputStream) throws Exception {
- outputStream.putNextEntry (entry);
-
- if (!entry.isDirectory ()) {
- InputStream is = new BufferedInputStream (jar.getInputStream (entry));
- try {
- byte[] buffer = new byte[16384];
- while (true) {
- int numRead = is.read (buffer, 0, 16384);
- if (numRead == 0 || numRead == -1) {
- break;
- }
-
- outputStream.write (buffer, 0, numRead);
- }
- } finally {
- is.close ();
- }
- }
- }
-
- protected void findJarFile () throws BuildException {
- File[] allFiles = baseName.getParentFile ().listFiles ();
- if (allFiles == null) {
- throw new BuildException ("Unable to find any file with base name " + baseName.getName ()
- + " in " + baseName.getParentFile ().getPath ());
- }
-
- long newestDate = 0;
- for (int i = 0; i < allFiles.length; i++) {
- String name = allFiles[i].getName ();
- if (name.startsWith (baseName.getName ()) && name.endsWith (".jar") &&
- allFiles[i].lastModified () > newestDate) {
- jarFile = allFiles[i];
- newestDate = allFiles[i].lastModified ();
- }
- }
-
- if (jarFile == null) {
- throw new BuildException ("Unable to find any file with base name " + baseName.getName ()
- + " in " + baseName.getParentFile ().getPath ());
- }
- }
-
- public void execute () throws BuildException {
- if (inMaven) {
- findJarFile ();
- }
- if (!jarFile.exists ()) {
- log ("Can't find " + jarFile.getPath ());
- return;
- }
- try {
- log ("Creating attribute index for " + jarFile.getPath ());
-
- JarFile jar = new JarFile (jarFile);
- File newJarFile = new File (jarFile.getPath () + ".new");
- JarOutputStream output = new JarOutputStream (new FileOutputStream (newJarFile));
- try {
- Enumeration enum = jar.entries ();
- while (enum.hasMoreElements ()) {
- JarEntry entry = (JarEntry) enum.nextElement ();
- if (!entry.isDirectory ()) {
- String className = entry.getName ();
- if (className.endsWith (SUFFIX)) {
- className = className.replace ('/', '.').replace ('\\', '.').substring (0, className.length () - SUFFIX.length ());
- classes.add (className);
- }
- }
-
- if (!entry.getName ().equals (INDEX_FILENAME)) {
- copyEntry (jar, entry, output);
- }
- }
-
- output.putNextEntry (new JarEntry (INDEX_FILENAME));
-
- Iterator attrs = classes.iterator ();
- while (attrs.hasNext ()) {
- String className = (String) attrs.next ();
- output.write (("Class: " + className + "\n").getBytes ());
- }
- } finally {
- output.close ();
- jar.close ();
- }
-
- jarFile.delete ();
- newJarFile.renameTo (jarFile);
- } catch (Exception e) {
- e.printStackTrace ();
- throw new BuildException (e.toString ());
- }
- }
- }