You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ri...@apache.org on 2006/06/14 17:22:08 UTC

svn commit: r414287 [2/6] - in /incubator/felix/trunk: org.apache.felix.ipojo.arch/ org.apache.felix.ipojo.arch/src/ org.apache.felix.ipojo.arch/src/main/ org.apache.felix.ipojo.arch/src/main/java/ org.apache.felix.ipojo.arch/src/main/java/org/ org.apa...

Added: incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/Clazz.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/Clazz.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/Clazz.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/Clazz.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,190 @@
+package org.apache.felix.ipojo.plugin;
+
+import java.io.*;
+import java.util.*;
+
+public class Clazz {
+	static byte	SkipTable[]	= {0, // 0 non existent
+		-1, // 1 CONSTANT_utf8 UTF 8, handled in
+		// method
+		-1, // 2
+		4, // 3 CONSTANT_Integer
+		4, // 4 CONSTANT_Float
+		8, // 5 CONSTANT_Long (index +=2!)
+		8, // 6 CONSTANT_Double (index +=2!)
+		-1, // 7 CONSTANT_Class
+		2, // 8 CONSTANT_String
+		4, // 9 CONSTANT_FieldRef
+		4, // 10 CONSTANT_MethodRef
+		4, // 11 CONSTANT_InterfaceMethodRef
+		4, // 12 CONSTANT_NameAndType
+						};
+
+	Set			imports = new HashSet();
+	String		path;
+	Jar			jar;
+	
+	public Clazz(Jar jar, String path, InputStream in) throws IOException {
+		this.path = path;
+		this.jar = jar;
+		DataInputStream din = new DataInputStream(in);
+		parseClassFile(din);
+	}
+
+
+	void parseClassFile(DataInputStream in)
+			throws IOException {
+		Set classes = new HashSet();
+		Set descriptors = new HashSet();
+		Hashtable pool = new Hashtable();
+		try {
+			int magic = in.readInt();
+			if (magic != 0xCAFEBABE)
+				throw new IOException(
+						"Not a valid class file (no CAFEBABE header)");
+			in.readShort(); // minor version
+			in.readShort(); // major version
+			int count = in.readUnsignedShort();
+			process: for (int i = 1; i < count; i++) {
+				byte tag = in.readByte();
+				switch (tag) {
+					case 0 :
+						break process;
+					case 1 :
+						// CONSTANT_Utf8
+						String name = in.readUTF();
+						pool.put(new Integer(i), name);
+						break;
+					// A Class constant is just a short reference in
+					// the constant pool
+					case 7 :
+						// CONSTANT_Class
+						Integer index = new Integer(in.readShort());
+						classes.add(index);
+						break;
+					// For some insane optimization reason are
+					// the long and the double two entries in the
+					// constant pool. See 4.4.5
+					case 5 :
+						// CONSTANT_Long
+					case 6 :
+						// CONSTANT_Double
+						in.skipBytes(8);
+						i++;
+						break;
+
+					// Interface Method Ref
+					case 12 :
+						in.readShort(); // Name index
+						int descriptorIndex = in.readShort();
+						descriptors.add(new Integer(descriptorIndex));
+						break;
+
+					// We get the skip count for each record type
+					// from the SkipTable. This will also automatically
+					// abort when
+					default :
+						if (tag == 2)
+							throw new IOException("Invalid tag " + tag);
+						in.skipBytes(SkipTable[tag]);
+						break;
+				}
+			}
+		}
+		catch (Exception e) {
+			e.printStackTrace();
+			return;
+		}
+		//
+		// Now iterate over all classes we found and
+		// parse those as well. We skip duplicates
+		//
+
+		for (Iterator e = classes.iterator(); e.hasNext();) {
+			Integer n = (Integer) e.next();
+			String next = (String) pool.get(n);
+			if (next != null) {
+				String normalized = normalize(next);
+				if (normalized != null) {
+                    // For purposes of trying to guess the activator class, we assume
+                    // that any class that references the BundleActivator interface
+                    // must be a BundleActivator implementation.
+					if ( normalized.startsWith("org/osgi/framework/BundleActivator")) {
+						String cname = path.replace('/', '.');
+						cname = cname.substring(0,cname.length()-".class" .length());
+						jar.addActivator(cname);
+					}
+					String pack = getPackage(normalized);
+					if (!pack.startsWith("java."))
+						imports.add(pack);
+				}
+			}
+			else
+				throw new IllegalArgumentException("Invalid class, parent=");
+		}
+		for (Iterator e = descriptors.iterator(); e.hasNext();) {
+			Integer n = (Integer) e.next();
+			String prototype = (String) pool.get(n);
+			if (prototype != null)
+				parseDescriptor(prototype);
+		}
+	}
+
+	void parseDescriptor(String prototype) {
+		addReference(prototype);
+		StringTokenizer st = new StringTokenizer(prototype, "(;)", true);
+		while (st.hasMoreTokens()) {
+			if (st.nextToken().equals("(")) {
+				String token = st.nextToken();
+				while (!token.equals(")")) {
+					addReference(token);
+					token = st.nextToken();
+				}
+				token = st.nextToken();
+				addReference(token);
+			}
+		}
+	}
+
+	private void addReference(String token) {
+		if (token.startsWith("L")) {
+			String clazz = normalize(token.substring(1));
+			if (clazz.startsWith("java/"))
+				return;
+			String pack = getPackage(clazz);
+			imports.add(pack);
+		}
+	}
+
+	static String normalize(String s) {
+		if (s.startsWith("[L"))
+			return normalize(s.substring(2));
+		if (s.startsWith("["))
+			if (s.length() == 2)
+				return null;
+			else
+				return normalize(s.substring(1));
+		if (s.endsWith(";"))
+			return normalize(s.substring(0, s.length() - 1));
+		return s + ".class";
+	}
+
+	static String getPackage(String clazz) {
+		int n = clazz.lastIndexOf('/');
+		if (n < 0)
+			return ".";
+		return clazz.substring(0, n).replace('/', '.');
+	}
+
+
+	public Collection getReferred() {
+		return imports;
+	}
+
+
+	public Object getPath() {
+		return path;
+	}
+
+
+}

Propchange: incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/Clazz.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/IpojoPluginConfiguration.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/IpojoPluginConfiguration.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/IpojoPluginConfiguration.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/IpojoPluginConfiguration.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,21 @@
+package org.apache.felix.ipojo.plugin;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class IpojoPluginConfiguration {
+
+	private static Logger logger;
+	
+	public static Level logLevel = Level.WARNING; 
+	
+	public static Logger getLogger() {
+		if (logger == null) {
+			String name = "org.apache.felix.ipojo.tools.plugin";
+			logger = Logger.getLogger(name);
+			logger.setLevel(logLevel);
+		}
+		return logger;
+	}
+	
+}

Propchange: incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/IpojoPluginConfiguration.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/Jar.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/Jar.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/Jar.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/Jar.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,176 @@
+package org.apache.felix.ipojo.plugin;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+import java.util.zip.*;
+
+public class Jar {
+	Map			resources	= new TreeMap();
+	Map			imports		= new HashMap();
+	Map			exports		= new HashMap();
+	Manifest	manifest;
+	boolean		manifestFirst;
+	String		name;
+	Jar			parent;
+	List		activators	= new ArrayList();
+
+	public Jar(Jar parent, String name, InputStream in) throws IOException {
+		this.name = name;
+		this.parent = parent;
+		ZipInputStream jar = new ZipInputStream(in);
+		ZipEntry entry = jar.getNextEntry();
+		boolean first = true;
+		while (entry != null) {
+			String path = entry.getName();
+
+			if (path.endsWith(".class")) {
+				Clazz clazz = new Clazz(this, path, jar);
+				resources.put(path, clazz);
+			}
+			else if (path.endsWith(".jar")) {
+				Jar pool = new Jar(this, path, jar);
+				resources.put(path, pool);
+			}
+			else if (path.endsWith("/packageinfo")
+					&& !path.startsWith("OSGI-OPT")) {
+				String version = parsePackageInfo(jar, exports);
+				resources.put(path, version);
+			}
+			else if (path.equals("META-INF/MANIFEST.MF")) {
+				manifestFirst = first;
+				manifest = new Manifest(jar);
+			}
+			else
+				resources.put(path, null);
+
+			entry = jar.getNextEntry();
+			if (!path.endsWith("/"))
+				first = false;
+		}
+	}
+
+	public Jar(Jar parent, String name, File rootDir) throws IOException {
+		this.name = name;
+		this.parent = parent;
+		traverse(rootDir.getAbsolutePath().length(), rootDir, rootDir.list());
+	}
+
+	void traverse(int root, File dir, String list[]) throws IOException {
+		for (int i = 0; i < list.length; i++) {
+			File sub = new File(dir, list[i]);
+			if (sub.isDirectory())
+				traverse(root, sub, sub.list());
+			else {
+				String path = sub.getAbsolutePath().substring(root + 1)
+						.replace(File.separatorChar, '/');
+				FileInputStream in = new FileInputStream(sub);
+
+				if (path.endsWith(".class")) {
+					Clazz clazz = new Clazz(this, path, in);
+					resources.put(path, clazz);
+				}
+				else if (path.endsWith(".jar")) {
+					Jar pool = new Jar(this, path, in);
+					resources.put(path, pool);
+				}
+				else if (path.endsWith("/packageinfo")
+						&& !path.startsWith("OSGI-OPT")) {
+					String version = parsePackageInfo(in, exports);
+					resources.put(path, version);
+				}
+				else if (path.endsWith("META-INF/MANIFEST.MF")) {
+					manifest = new Manifest(in);
+				}
+				else
+					resources.put(path, null);
+			}
+		}
+	}
+
+	private static String parsePackageInfo(InputStream jar, Map exports)
+			throws IOException {
+		try {
+			byte[] buf = collect(jar, 0);
+			String line = new String(buf);
+			StringTokenizer qt = new StringTokenizer(line, " \r\n\t");
+			if (qt.hasMoreElements()) {
+				qt.nextToken();
+				if (qt.hasMoreElements()) {
+					String version = qt.nextToken();
+					return version;
+				}
+			}
+		}
+		catch (Exception e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+	/**
+	 * Convenience method to turn an inputstream into a byte array. The method
+	 * uses a recursive algorithm to minimize memory usage.
+	 * 
+	 * @param in stream with data
+	 * @param offset where we are in the stream
+	 * @returns byte array filled with data
+	 */
+	private static byte[] collect(InputStream in, int offset)
+			throws IOException {
+		byte[] result;
+		byte[] buffer = new byte[10000];
+		int size = in.read(buffer);
+		if (size <= 0)
+			return new byte[offset];
+		else
+			result = collect(in, offset + size);
+		System.arraycopy(buffer, 0, result, offset, size);
+		return result;
+	}
+
+	public Manifest getManifest() {
+		return manifest;
+	}
+
+	public Object getEntry(String resource) {
+		return resources.get(resource);
+	}
+
+	public boolean exists(String jarOrDir) {
+		return resources.keySet().contains(jarOrDir);
+	}
+
+	public Set getEntryPaths(String prefix) {
+		Set result = new TreeSet();
+		for (Iterator i = resources.keySet().iterator(); i.hasNext();) {
+			String path = (String) i.next();
+			if (path.startsWith(prefix))
+				result.add(path);
+		}
+		return result;
+	}
+
+	String getName() {
+		return name;
+	}
+
+	public String toString() {
+		return getName();
+	}
+
+	public void addActivator(String path) {
+		if (parent != null)
+			parent.addActivator(path);
+		else {
+			activators.add(path);
+		}
+
+	}
+
+    public boolean containsActivator(String path) {
+        if (parent != null)
+            return parent.containsActivator(path);
+        return activators.contains(path);
+    }
+}

Propchange: incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/Jar.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/OsgiJarMojo.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/OsgiJarMojo.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/OsgiJarMojo.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/OsgiJarMojo.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,869 @@
+/*
+ *   Copyright 2005 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.felix.ipojo.plugin;
+
+//import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+//import java.io.InputStreamReader;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.felix.ipojo.manipulation.Manipulator;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+//import org.apache.felix.ipojo.parser.KXml2SAXParser;
+import org.apache.felix.ipojo.parser.ManifestMetadataParser;
+import org.apache.felix.ipojo.parser.ParseException;
+//import org.apache.felix.ipojo.parser.XMLGenericMetadataParser;
+import org.apache.felix.ipojo.parser.XMLMetadataParser;
+import org.apache.maven.archiver.MavenArchiveConfiguration;
+import org.apache.maven.archiver.MavenArchiver;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.DependencyResolutionRequiredException;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.archiver.ArchiverException;
+import org.codehaus.plexus.archiver.jar.JarArchiver;
+import org.codehaus.plexus.archiver.jar.ManifestException;
+import org.codehaus.plexus.util.FileUtils;
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderFactory;
+//import org.xmlpull.v1.XmlPullParserException;
+
+/**
+ * Package an OSGi jar "bundle."
+ * 
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Apache Felix Project</a>
+ * @version $Rev$, $Date$
+ * @goal ipojo-bundle
+ * @phase package
+ * @requiresDependencyResolution runtime
+ * @description build an OSGi bundle jar
+ */
+public class OsgiJarMojo extends AbstractMojo {
+	private static final String[]		EMPTY_STRING_ARRAY		= {};
+
+	int									bundleManifestVersion	= 1;
+
+	/**
+	 * The Maven project.
+	 * 
+	 * @parameter expression="${project}"
+	 * @required
+	 * @readonly
+	 */
+	private MavenProject				project;
+
+	/**
+	 * The directory for the generated JAR.
+	 * 
+	 * @parameter expression="${project.build.directory}"
+	 * @required
+	 */
+	private String						buildDirectory;
+
+	/**
+	 * The directory containing generated classes.
+	 * 
+	 * @parameter expression="${project.build.outputDirectory}"
+	 * @required
+	 * @readonly
+	 */
+	private File						outputDirectory;
+
+	/**
+	 * The name of the generated JAR file.
+	 * 
+	 * @parameter alias="jarName" expression="${project.build.finalName}"
+	 * @required
+	 */
+	private String						jarName;
+
+	/**
+	 * The Jar archiver.
+	 * 
+	 * @parameter expression="${component.org.codehaus.plexus.archiver.Archiver#jar}"
+	 * @required
+	 */
+	private JarArchiver					jarArchiver;
+
+	/**
+	 * The maven archive configuration to use.
+	 */
+	private MavenArchiveConfiguration	archiveConfig			= new MavenArchiveConfiguration();
+
+	/**
+	 * The comma separated list of tokens to include in the JAR. Default is
+	 * '**'.
+	 * 
+	 * @parameter alias="includes"
+	 */
+	private String						jarSourceIncludes		= "**";
+
+	/**
+	 * The comma separated list of tokens to exclude from the JAR.
+	 * 
+	 * @parameter alias="excludes"
+	 */
+	private String						jarSourceExcludes;
+
+	/**
+	 * @parameter
+	 */
+	private String						manifestFile;
+
+	/**
+	 * @parameter expression="${org.apache.felix.ipojo.tools.maven.plugin.OsgiManifest}"
+	 */
+	private OsgiManifest				osgiManifest;
+	
+	private String[][] namespaces; 
+
+	/**
+	 * Execute this Mojo
+	 * 
+	 * @throws MojoExecutionException
+	 */
+	public void execute() throws MojoExecutionException {
+		File jarFile = new File(buildDirectory, jarName + ".jar");
+
+		try {
+			performPackaging(jarFile);
+		}
+		catch (Exception e) {
+			throw new MojoExecutionException("Error assembling JAR bundle", e);
+		}
+	}
+
+	/**
+	 * Generates the JAR bundle file.
+	 * 
+	 * @param jarFile the target JAR file
+	 * @throws IOException
+	 * @throws ArchiverException
+	 * @throws ManifestException
+	 * @throws DependencyResolutionRequiredException
+	 */
+	private void performPackaging(File jarFile) throws IOException,
+			ArchiverException, ManifestException,
+			DependencyResolutionRequiredException, MojoExecutionException {
+
+		verifyDeclaredBundleManifestVersion();
+
+		getLog().info("Generating JAR bundle " + jarFile.getAbsolutePath());
+
+		MavenArchiver archiver = new MavenArchiver();
+
+		archiver.setArchiver(jarArchiver);
+		archiver.setOutputFile(jarFile);
+
+		addManifestFile();
+		addManifestEntries();
+
+		// Add the JARs that were specified in the POM
+		// as "not" provided
+		addEmbeddedJars();
+		addBundleVersion();
+		
+		// Insert iPOJO Manipulation
+		iPojoManipulation();
+
+		jarArchiver.addDirectory(outputDirectory, getIncludes(), getExcludes());
+
+		// Parse the output directory as if it was a JAR file.
+		// This creates special entries for classes, packageinfo
+		// and embedded JAR files (which are parsed as well).
+		Jar mainJar = new Jar(null, jarName, outputDirectory);
+
+		// Calculate the Bundle Classpath from the embedded
+		// JAR files. We hardcode the bcp as ., <embedded jars>
+		// TODO we add all the found JARs to the Bcp, maybe we
+		// should look if they are needed by traversing the imports.
+		List bundleClassPath = getBundleClassPath(mainJar);
+		bundleClassPath.add(0, ".");
+		createBundleClasspathHeader(bundleClassPath);
+
+		// Calculate the exports (contained) and imports (referred)
+		// The bundleClassPath contains the JARs in the right order
+		Set contained = new HashSet(); // package name
+		Set referred = new HashSet(); // package name
+		Map uses = new HashMap(); // package name => Set of package name
+
+		// Iterate over the bundle class path and calculate the contained
+		// and referred packages as well as the uses.
+		for (Iterator i = bundleClassPath.iterator(); i.hasNext();) {
+			String path = (String) i.next();
+			Jar jar = path.equals(".") ? mainJar : (Jar) mainJar.resources
+					.get(path);
+			analyzeJar(jar, contained, referred, uses);
+		}
+
+		referred.removeAll(contained);
+
+		Map exports = parseHeader(osgiManifest.getExportPackage());
+		Map imports = parseHeader(osgiManifest.getImportPackage());
+		Map dynamicImports = parseHeader(osgiManifest.getDynamicImportPackage());
+
+		if (dynamicImports != null) {
+			// Remove any dynamic imports from the referred set.
+			referred = new HashSet(referred);
+			referred.removeAll(dynamicImports.keySet());
+		}
+
+		if (exports != null) {
+			verifyDeclaredExports(exports, contained);
+			createExportHeader(exports, uses);
+		}
+
+		// If the POM file contains an import declaration,
+		// we verify its validity. Otherwise, we generate the
+		// import package header from the referred. Exports
+		// are added to automatically imports for R4 bundles.
+		if (imports == null) {
+			createImportHeader(referred, exports == null ? new HashSet()
+					: exports.keySet());
+		}
+		else {
+			verifyDeclaredImports(referred, imports);
+		}
+
+		//verifyBundleActivator(mainJar); // Replace it by setBundleActivator
+		
+		
+		archiver.createArchive(project, archiveConfig);
+		project.getArtifact().setFile(jarFile);
+	}
+	
+	private Element[] parseXMLMetadata(String path) throws MojoExecutionException {
+		File metadata = new File(outputDirectory+path);
+		URL url;
+		Element[] components = null;
+		try {
+			url = metadata.toURI().toURL();
+			if (url == null) { 
+				getLog().error("No metadata at : " + outputDirectory+path);
+				throw new MojoExecutionException("[iPOJO] No metadata at : " + outputDirectory+path); 
+			}
+			
+			InputStream stream = url.openStream();
+
+//	        //Open the file and parse :
+//			BufferedReader in = new BufferedReader(new InputStreamReader(stream));
+//		    XMLGenericMetadataParser handler = new XMLGenericMetadataParser();
+//		    KXml2SAXParser parser;
+//			parser = new KXml2SAXParser(in);
+//			parser.parseXML(handler);
+//		    stream.close();
+			
+			XMLReader parser = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");
+			XMLMetadataParser handler = new XMLMetadataParser();
+			parser.setContentHandler(handler);
+			InputSource is = new InputSource(stream);
+			parser.parse(is);
+		    
+		    components = handler.getComponentsMetadata();
+
+		    
+		} catch (MalformedURLException e) {
+			getLog().error("Malformed URL for " + outputDirectory+path+ "("+e.getMessage()+")");
+			throw new MojoExecutionException("[iPOJO] Malformed URL for " + outputDirectory+path);
+		} catch (IOException e) { 
+        	getLog().error("Cannot open the file : " + outputDirectory+path + "("+e.getMessage()+")");
+			throw new MojoExecutionException("[iPOJO] Cannot open the file : " + outputDirectory+path);
+//        } catch (XmlPullParserException e) {
+//        	getLog().error("Error when  parsing the XML file " + outputDirectory+path+ "("+e.getMessage()+")");
+//			throw new MojoExecutionException("[iPOJO] Error when  parsing the XML file " + outputDirectory+path);
+		} catch (Exception e) {
+			getLog().error("Parsing Error when parsing the XML file " + outputDirectory+path+ "("+e.getMessage()+")");
+			throw new MojoExecutionException("[iPOJO] Parsing Error when parsing the XML file " + outputDirectory+path);
+		}
+		
+		if(components == null || components.length == 0) {
+			getLog().error("No component in " + outputDirectory+path);
+			throw new MojoExecutionException("[iPOJO] No component in " + outputDirectory+path);
+		}
+		
+		return components;
+	}
+	
+	private Element[] parseManifestMetadata(String metadata) throws MojoExecutionException {
+		Element[] components = null;
+		ManifestMetadataParser parser = new ManifestMetadataParser();
+    	try {
+			parser.parse(metadata);
+			components = parser.getComponentsMetadata();
+		} catch (ParseException e) {
+			getLog().error("Parsing Error when parsing the Manifest metadata " +  metadata + "("+e.getMessage()+")");
+			throw new MojoExecutionException("[iPOJO] Parsing Error when parsing the Manifest metadata " +  metadata);
+			
+		}
+    	
+		if(components == null || components.length == 0) {
+			getLog().error("No component in " + metadata);
+			throw new MojoExecutionException("[iPOJO] No component in " + metadata);
+		}
+        
+        return components;
+	}
+	
+	private void iPojoManipulation() throws MojoExecutionException {
+		//Try to read the content of a file of the ouptut directory
+		getLog().info("iPOJO Manipulation ...");
+		
+		Element[] components = null;
+		
+		// Get the metadata.xml location 
+		String path = (String) osgiManifest.getEntries().get("iPOJO-Metadata");
+		
+		if(path != null) {
+			if(!path.startsWith("/")) { path = "/" + path; }
+			components = parseXMLMetadata(path);
+		} else {
+			String meta_ = (String) osgiManifest.getEntries().get("iPOJO-Components");
+			if(meta_ != null) {
+				components = parseManifestMetadata(meta_);
+			} else {
+				getLog().error("Neither iPOJO-Metadata nor iPOJO-Components are in the manifest, please in the osgi-bundle packaging instead og ipojo-bundle");
+				throw new MojoExecutionException("[iPOJO] Neither iPOJO-Metadata nor iPOJO-Components are in the manifest");
+			}
+				
+		}
+		
+			
+		Manipulator manipulator = new Manipulator();
+		String[] metadata = new String[components.length];
+		String meta = "";
+		if(namespaces == null) { namespaces = new String[components.length][]; }
+        for(int i = 0; i < components.length; i++) {
+        	getLog().info("Component Class Name : " + components[i].getAttribute("className"));
+        	namespaces[i] = components[i].getNamespaces();
+        	try {
+				manipulator.preProcess(components[i].getAttribute("className"), outputDirectory);
+			} catch (Exception e) {
+				getLog().error("Manipulation error in the class : " + components[i].getAttribute("className") + "("+e.getMessage()+")");
+				throw new MojoExecutionException("[iPOJO] Manipulation error in the class : " + components[i].getAttribute("className"));
+			}
+        	
+        	getLog().info("Add manipulation metadata for : " + components[i].getAttribute("className"));
+        	// Insert information to metadata
+        	Element elem = new Element("Manipulation", "");
+        	for(int j = 0; j < manipulator.getInterfaces().length; j++) {
+        		// Create an interface element for each implemented interface
+        		Element itf = new Element("Interface", "");
+        		Attribute att =new Attribute("name", manipulator.getInterfaces()[j]);
+        		itf.addAttribute(att);
+        		elem.addElement(itf);
+        	}
+
+        	for(Iterator it = manipulator.getFields().keySet().iterator(); it.hasNext(); ) {
+        		Element field = new Element("Field", "");
+        		String name = (String) it.next();
+        		String type = (String) manipulator.getFields().get(name);
+        		Attribute attName =new Attribute("name", name);
+        		Attribute attType =new Attribute("type", type);
+        		field.addAttribute(attName);
+        		field.addAttribute(attType);
+        		elem.addElement(field);
+        	}
+
+        	components[i].addElement(elem);
+        	
+        	// Transform the metadate to manifest metadata
+        	metadata[i] = buildManifestMetadata(components[i], "");
+        	meta = meta + metadata[i];
+        }
+        
+        getLog().info("Metadata of the bundles : " + meta);
+	    archiveConfig.addManifestEntry("iPOJO-Components", meta);
+	        
+	    getLog().info("Set the bundle activator");
+	    setBundleActivator();
+			
+	    getLog().info("iPOJO Manipulation ... SUCCESS");
+		
+	}
+
+	private String buildManifestMetadata(Element element, String actual) {
+		String result="";
+		if(element.getNameSpace().equals("")) { result = actual + element.getName() + " { "; }
+		else { result = actual + element.getNameSpace()+":"+element.getName() + " { ";	}
+		
+		for(int i = 0; i < element.getAttributes().length; i++) {
+			if(element.getAttributes()[i].getNameSpace().equals("")) { 
+				result = result + "$" + element.getAttributes()[i].getName() + "="+element.getAttributes()[i].getValue() + " ";
+			}
+			else {
+				result = result + "$" + element.getAttributes()[i].getNameSpace()+ ":" + element.getAttributes()[i].getName() + "="+element.getAttributes()[i].getValue() + " ";
+			}
+		}
+		for(int i = 0; i < element.getElements().length; i++) {
+			result = buildManifestMetadata(element.getElements()[i], result);
+		}
+		return result +"}";
+	}
+
+	private void setBundleActivator() throws MojoExecutionException {
+		archiveConfig.addManifestEntry("Bundle-Activator", "org.apache.felix.ipojo.Activator");		
+	}
+
+//	private void verifyBundleActivator(Jar mainJar) {
+//		String ba = osgiManifest.getBundleActivator();
+//		if (ba == null || ba.trim().length() == 0) {
+//			switch ( mainJar.activators.size() ) {
+//				case 0: break;
+//				case 1: archiveConfig.addManifestEntry("Bundle-Activator", mainJar.activators.get(0));
+//				break;
+//				default:
+//					getLog().info("[OSGi] No Bundle-Activator specified and multiple found" );
+//				break;
+//			}
+//		}
+//		else {
+//			if( ! mainJar.activators.contains(ba))
+//				getLog().warn("[OSGi] UNABLE TO VERIFY BUNDLE ACTIVATOR: " + ba);
+//		}
+//	}
+
+	private void createBundleClasspathHeader(List bundleClassPath) {
+		StringBuffer sb = new StringBuffer();
+		String del = ".,";
+		for (Iterator i = bundleClassPath.iterator(); i.hasNext();) {
+			sb.append(del);
+			sb.append(i.next());
+			del = ",";
+		}
+		if (sb.length() > 0)
+			archiveConfig.addManifestEntry("Bundle-Classpath", sb.toString());
+	}
+
+	/**
+	 * Iterate over the declared exports from the POM, verify that they are
+	 * present, add the uses clause if necessary and finally add the manifest
+	 * entry.
+	 * 
+	 * @param contained Set of contained packages
+	 * @param exports Map with the export clauses from the POM
+	 * @param uses Map with use clauses
+	 * @throws MojoExecutionException
+	 */
+	void verifyDeclaredExports(Map exports, Set contained)
+			throws MojoExecutionException {
+		Set declaredExports = exports.keySet();
+		for (Iterator i = declaredExports.iterator(); i.hasNext();) {
+			String pack = (String) i.next();
+			if (!contained.contains(pack)) {
+				getLog()
+						.error("[OSGi] EXPORTED PACKAGE NOT IN BUNDLE: " + pack);
+				throw new MojoExecutionException(
+						"Exported Package not found in bundle or JARs on bundle class path "
+								+ pack);
+			}
+
+		}
+	}
+
+	/**
+	 * Print out the export headers after adding the uses clause.
+	 * 
+	 * @param exports
+	 * @param uses
+	 * @throws MojoExecutionException
+	 */
+	void createExportHeader(Map exports, Map uses)
+			throws MojoExecutionException {
+		if (exports.size() > 0) {
+			Set declaredExports = exports.keySet();
+			for (Iterator i = declaredExports.iterator(); i.hasNext();) {
+				String pack = (String) i.next();
+				Map clause = (Map) exports.get(pack);
+
+				if (bundleManifestVersion >= 2) {
+					Set t = (Set) uses.get(pack);
+					if (t != null && !t.isEmpty()) {
+						StringBuffer sb = new StringBuffer();
+						String del = "\"";
+						for (Iterator u = t.iterator(); u.hasNext();) {
+							String usedPackage = (String) u.next();
+							if (!usedPackage.equals(pack)) {
+								sb.append(del);
+								sb.append(usedPackage);
+								del = ",";
+							}
+						}
+						sb.append("\"");
+						clause.put("uses:", sb.toString());
+					}
+				}
+			}
+			archiveConfig.addManifestEntry(
+					"Export-Package",
+					printClauses(exports));
+		}
+	}
+
+	/**
+	 * Verify that the declared imports match the referred packages.
+	 * 
+	 * @param referred referred package
+	 * @param imports imported packages from POM
+	 * @throws MojoExecutionException
+	 */
+	void verifyDeclaredImports(Set referred, Map imports)
+			throws MojoExecutionException {
+		Set declaredImports = imports.keySet();
+		Set test = new HashSet(referred);
+		test.removeAll(declaredImports);
+		for (Iterator m = test.iterator(); m.hasNext();) {
+			Object o = m.next();
+			if(o.equals("org.apache.felix.ipojo")) { break; } // Skip iPOJO, it will be add at the end of the packaging
+			getLog().warn("[OSGi] MISSING IMPORT: " + o);
+			//throw new MojoExecutionException("Missing Import " + o);
+		}
+
+		test = new HashSet(declaredImports);
+		test.removeAll(referred);
+		for (Iterator m = test.iterator(); m.hasNext();) {
+			getLog().warn("[OSGi] SUPERFLUOUS IMPORT: " + m.next());
+			getLog()
+					.warn(
+							"[OSGi] Removing the POM Import-Package element will automatically generate the import clauses");
+		}
+	}
+
+	/**
+	 * Standard OSGi header parser. This parser can handle the format clauses
+	 * ::= clause ( ',' clause ) + clause ::= name ( ';' name ) (';' key '='
+	 * value )
+	 * 
+	 * This is mapped to a Map { name => Map { attr|directive => value } }
+	 * 
+	 * @param value
+	 * @return
+	 * @throws MojoExecutionException
+	 */
+	static Map parseHeader(String value) throws MojoExecutionException {
+		if (value == null || value.trim().length() == 0)
+			return null;
+
+		Map result = new HashMap();
+		QuotedTokenizer qt = new QuotedTokenizer(value, ";=,");
+		char del;
+		do {
+			boolean hadAttribute = false;
+			Map clause = new HashMap();
+			List aliases = new ArrayList();
+			aliases.add(qt.nextToken());
+			del = qt.getSeparator();
+			while (del == ';') {
+				String adname = qt.nextToken();
+				if (qt.getSeparator() != '=') {
+					if (hadAttribute)
+						throw new MojoExecutionException(
+								"Header contains name field after attribute or directive: "
+										+ adname + " from " + value);
+					aliases.add(adname);
+				}
+				else {
+					String advalue = qt.nextToken();
+					clause.put(adname, advalue);
+					del = qt.getSeparator();
+					hadAttribute = true;
+				}
+			}
+			for (Iterator i = aliases.iterator(); i.hasNext();) {
+				result.put(i.next(), clause);
+			}
+		} while (del == ',');
+		return result;
+	}
+
+	/**
+	 * Create the import header, taking into account R4 automatic import clauses
+	 * for the exports.
+	 * 
+	 * @param referred
+	 * @param contained
+	 */
+	void createImportHeader(Set referred, Set contained) {
+		if (referred.isEmpty())
+			return;
+
+		referred = new TreeSet(referred);
+
+		if (bundleManifestVersion > 1) {
+			referred.addAll(contained);
+		}
+
+		StringBuffer sb = new StringBuffer();
+		String del = "";
+
+		for (Iterator i = referred.iterator(); i.hasNext();) {
+			sb.append(del);
+			sb.append(i.next());
+			del = ", ";
+		}
+		
+		// Add handler import
+		for(int j = 0; j < namespaces.length; j++) {
+			for(int k = 0; k < namespaces[j].length; k++) {
+				if(! namespaces[j][k].equals("")) {
+					int lastIndex = namespaces[j][k].lastIndexOf('.');
+					String ns = namespaces[j][k].substring(0, lastIndex);
+					sb.append(del);
+					sb.append(ns);
+					del = ", ";
+				}
+			}
+		}
+		
+		archiveConfig.addManifestEntry("Import-Package", sb.toString());
+		getLog().info("Set Imports to : " + sb.toString());
+	}
+
+	/**
+	 * Calculate the bundle class path based on the list of JARs in our bundle.
+	 * This list includes outselves. We also calculate the Bundle-Classpath
+	 * header (a bit clumsy) This is a bit cheap, so maybe this needs to be
+	 * changed TODO
+	 * 
+	 * @param mainJar
+	 * @param sb
+	 * @return
+	 */
+	List getBundleClassPath(Jar mainJar) {
+		List result = new ArrayList();
+		for (Iterator i = mainJar.resources.keySet().iterator(); i.hasNext();) {
+			String path = (String) i.next();
+			Object resource = mainJar.resources.get(path);
+			if (resource instanceof Jar) {
+				result.add(path);
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * We traverse through al the classes that we can find and calculate the
+	 * contained and referred set and uses.
+	 * 
+	 * @param jar
+	 * @param contained
+	 * @param referred
+	 * @param uses
+	 */
+	void analyzeJar(Jar jar, Set contained, Set referred, Map uses) {
+		String prefix = "";
+		Set set = jar.getEntryPaths(prefix);
+		for (Iterator r = set.iterator(); r.hasNext();) {
+			String path = (String) r.next();
+			Object resource = jar.getEntry(path);
+			if (resource instanceof Clazz) {
+				Clazz clazz = (Clazz) resource;
+				String pathOfClass = path.substring(prefix.length());
+				String pack = Clazz.getPackage(pathOfClass);
+				contained.add(pack);
+				referred.addAll(clazz.getReferred());
+
+				// Add all the used packages
+				// to this package
+				Set t = (Set) uses.get(pack);
+				if (t == null)
+					uses.put(pack, t = new HashSet());
+				t.addAll(clazz.getReferred());
+				t.remove(pack);
+			}
+		}
+	}
+
+	/**
+	 * Print a standard Map based OSGi header.
+	 * 
+	 * @param exports map { name => Map { attribute|directive => value } }
+	 * @return the clauses
+	 */
+
+	String printClauses(Map exports) {
+		StringBuffer sb = new StringBuffer();
+		String del = "";
+		for (Iterator i = exports.keySet().iterator(); i.hasNext();) {
+			String name = (String) i.next();
+			Map map = (Map) exports.get(name);
+			sb.append(del);
+			sb.append(name);
+
+			for (Iterator j = map.keySet().iterator(); j.hasNext();) {
+				String key = (String) j.next();
+				String value = (String) map.get(key);
+				sb.append(";");
+				sb.append(key);
+				sb.append("=");
+				sb.append(value);
+			}
+			del = ", ";
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * Check if the BundleManifest version is set correctly, base the manifest
+	 * version on it.
+	 * 
+	 * @throws MojoExecutionException
+	 */
+	void verifyDeclaredBundleManifestVersion() throws MojoExecutionException {
+		String mfv = osgiManifest.getBundleManifestVersion();
+		if (mfv != null && mfv.trim().length() != 0) {
+			try {
+				bundleManifestVersion = Integer.parseInt(mfv);
+				if (bundleManifestVersion != 2)
+					throw new MojoExecutionException(
+							"Bundle-ManifestVersion must be 2, it is " + mfv);
+			}
+			catch (Exception e) {
+				throw new MojoExecutionException(
+						"Bundle-ManifestVersion must be an integer: " + mfv);
+			}
+		}
+	}
+
+	/**
+	 * TODO: Decide if we accept merging of entire manifest.mf files Here's a
+	 * big question to make a final decision at some point: Do accept merging of
+	 * manifest entries located in some file somewhere in the project directory?
+	 * If so, do we allow both file and configuration based entries to be
+	 * specified simultaneously and how do we merge these?
+	 */
+	private void addManifestFile() {
+		if (manifestFile != null) {
+			File file = new File(project.getBasedir().getAbsolutePath(),
+					manifestFile);
+			getLog().info(
+					"Manifest file: " + file.getAbsolutePath()
+							+ " will be used");
+			archiveConfig.setManifestFile(file);
+		}
+		else {
+			getLog().info("No manifest file specified. Default will be used.");
+		}
+	}
+
+	/**
+	 * Look for any OSGi specified manifest entries in the maven-osgi-plugin
+	 * configuration section of the POM. If we find some, then add them to the
+	 * target artifact's manifest.
+	 */
+	private void addManifestEntries() {
+		if (osgiManifest != null && osgiManifest.getEntries().size() > 0) {
+			Map entries = osgiManifest.getEntries();
+
+			getLog().info(
+					"Bundle manifest will be modified with the following entries: "
+							+ entries.toString());
+			archiveConfig.addManifestEntries(entries);
+		}
+		else {
+			getLog()
+					.info(
+							"No OSGi bundle manifest entries have been specified in the POM.");
+		}
+	}
+
+	/**
+	 * We are going to iterate through the POM's specified JAR dependencies. If
+	 * a dependency has a scope of either RUNTIME or COMPILE, then we'll JAR
+	 * them up inside the OSGi bundle artifact. We will then add the
+	 * Bundle-Classpath manifest entry.
+	 */
+	private void addEmbeddedJars() throws MojoExecutionException {
+		Set artifacts = project.getArtifacts();
+
+		for (Iterator it = artifacts.iterator(); it.hasNext();) {
+			Artifact artifact = (Artifact) it.next();
+			if (!Artifact.SCOPE_PROVIDED.equals(artifact.getScope())
+					&& !Artifact.SCOPE_TEST.equals(artifact.getScope())) {
+				String type = artifact.getType();
+
+				if ("jar".equals(type)) {
+					File depFile = artifact.getFile();
+
+					try {
+						FileUtils.copyFileToDirectory(depFile, outputDirectory);
+
+					}
+					catch (Exception e) {
+						String errmsg = "Error copying "
+								+ depFile.getAbsolutePath() + " to "
+								+ outputDirectory.getAbsolutePath();
+						throw new MojoExecutionException(errmsg, e);
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * Auto-set the bundle version.
+	 */
+	private void addBundleVersion() {
+		// Maven uses a '-' to separate the version qualifier,
+		// while OSGi uses a '.', so we need to convert to a '.'
+		StringBuffer sb = new StringBuffer(project.getVersion());
+		if (sb.indexOf("-") >= 0) {
+			sb.setCharAt(sb.indexOf("-"), '.');
+		}
+		archiveConfig.addManifestEntry("Bundle-Version", sb.toString());
+	}
+
+	/**
+	 * Returns a string array of the includes to be used when assembling/copying
+	 * the war.
+	 * 
+	 * @return an array of tokens to include
+	 */
+	private String[] getIncludes() {
+		return new String[] {jarSourceIncludes};
+	}
+
+	/**
+	 * Returns a string array of the excludes to be used when assembling/copying
+	 * the jar.
+	 * 
+	 * @return an array of tokens to exclude
+	 */
+	private String[] getExcludes() {
+		List excludeList = new ArrayList(FileUtils.getDefaultExcludesAsList());
+
+		if (jarSourceExcludes != null && !"".equals(jarSourceExcludes)) {
+			excludeList.add(jarSourceExcludes);
+		}
+
+		return (String[]) excludeList.toArray(EMPTY_STRING_ARRAY);
+	}
+}

Propchange: incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/OsgiJarMojo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/OsgiManifest.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/OsgiManifest.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/OsgiManifest.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/OsgiManifest.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,550 @@
+/*
+ *   Copyright 2005 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.felix.ipojo.plugin;
+
+import java.util.Properties;
+
+/**
+ * Hold values for an OSGi jar "bundle" manifest.
+ * 
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Apache Felix Project</a>
+ * @version $Rev$, $Date$
+ */
+public class OsgiManifest
+{
+    /**
+     * Bundle manifest header constants from the OSGi R4 framework constants.
+     */
+    private static final String BUNDLE_CATEGORY = "Bundle-Category";
+    // private static final String BUNDLE_CLASSPATH = "Bundle-ClassPath";
+    private static final String BUNDLE_COPYRIGHT = "Bundle-Copyright";
+    private static final String BUNDLE_DESCRIPTION = "Bundle-Description";
+    private static final String BUNDLE_NAME = "Bundle-Name";
+    private static final String BUNDLE_NATIVECODE = "Bundle-NativeCode";
+    private static final String EXPORT_PACKAGE = "Export-Package";
+    private static final String EXPORT_SERVICE = "Export-Service";
+    private static final String IMPORT_PACKAGE = "Import-Package";
+    private static final String DYNAMICIMPORT_PACKAGE = "DynamicImport-Package";
+    private static final String IMPORT_SERVICE = "Import-Service";
+    private static final String BUNDLE_VENDOR = "Bundle-Vendor";
+    private static final String BUNDLE_VERSION = "Bundle-Version";
+    private static final String BUNDLE_DOCURL = "Bundle-DocURL";
+    private static final String BUNDLE_CONTACTADDRESS = "Bundle-ContactAddress";
+    private static final String BUNDLE_ACTIVATOR = "Bundle-Activator";
+    private static final String BUNDLE_UPDATELOCATION = "Bundle-UpdateLocation";
+    private static final String BUNDLE_REQUIREDEXECUTIONENVIRONMENT = "Bundle-RequiredExecutionEnvironment";
+    private static final String BUNDLE_SYMBOLICNAME = "Bundle-SymbolicName";
+    private static final String BUNDLE_LOCALIZATION = "Bundle-Localization";
+    private static final String REQUIRE_BUNDLE = "Require-Bundle";
+    private static final String FRAGMENT_HOST = "Fragment-Host";
+    private static final String BUNDLE_MANIFESTVERSION = "Bundle-ManifestVersion";
+
+    private static final String BUNDLE_URL = "Bundle-URL";
+    private static final String BUNDLE_SOURCE = "Bundle-Source";
+    private static final String BUNDLE_DATE = "Bundle-Date";
+    private static final String METADATA_LOCATION = "Metadata-Location";
+    
+    // iPOJO Manifest Headers
+    private static final String IPOJO_METADATA ="iPOJO-Metadata";
+    private static final String IPOJO_COMPONENTS ="iPOJO-Components";
+
+    /**
+     * Instance variables corresponding to the R4 framework manifest headers
+     */
+    private String bundleCategory;
+    // private String bundleClassPath;
+    private String bundleCopyright;
+    private String bundleDescription;
+    private String bundleName;
+    private String bundleNativeCode;
+    private String exportPackage;
+    private String exportService;
+    private String importPackage;
+    private String dynamicImportPackage;
+    private String importService;
+    private String bundleVendor;
+    private String bundleVersion;
+    private String bundleDocUrl;
+    private String bundleContactAddress;
+    private String bundleActivator;
+    private String bundleUpdateLocation;
+    private String bundleRequiredExecutionEnvironment;
+    private String bundleSymbolicName;
+    private String bundleLocalization;
+    private String requireBundle;
+    private String fragmentHost;
+    private String bundleManifestVersion;
+
+    /**
+     * Instance variables supporting non-framework manifest headers
+     */
+    private String bundleUrl;
+    private String bundleSource;
+    private String bundleDate;
+    private String metadataLocation;
+    
+    /**
+     * iPOJO Headers
+     */
+    private String iPOJOMetadata;
+    private String iPOJOComponents;
+
+    private Properties entries = new Properties();
+
+    public Properties getEntries()
+    {
+        if ( getBundleCategory() != null )
+        {
+            entries.put( BUNDLE_CATEGORY, getBundleCategory() );
+        }
+
+        /*
+         if (getBundleClassPath() != null)
+         {
+         entries.put(BUNDLE_CLASSPATH, getBundleClassPath());
+         }
+         */
+
+        if ( getBundleCopyright() != null )
+        {
+            entries.put( BUNDLE_COPYRIGHT, getBundleCopyright() );
+        }
+
+        if ( getBundleDescription() != null )
+        {
+            entries.put( BUNDLE_DESCRIPTION, getBundleDescription() );
+        }
+
+        if ( getBundleName() != null )
+        {
+            entries.put( BUNDLE_NAME, getBundleName() );
+        }
+
+        if ( getBundleNativeCode() != null )
+        {
+            entries.put( BUNDLE_NATIVECODE, getBundleNativeCode() );
+        }
+
+        if ( getExportPackage() != null )
+        {
+            entries.put( EXPORT_PACKAGE, getExportPackage() );
+        }
+
+        if ( getExportService() != null )
+        {
+            entries.put( EXPORT_SERVICE, getExportService() );
+        }
+
+        if ( getImportPackage() != null )
+        {
+            entries.put( IMPORT_PACKAGE, getImportPackage() );
+        }
+
+        if ( getDynamicImportPackage() != null )
+        {
+            entries.put( DYNAMICIMPORT_PACKAGE, getDynamicImportPackage() );
+        }
+
+        if ( getImportService() != null )
+        {
+            entries.put( IMPORT_SERVICE, getImportService() );
+        }
+
+        if ( getBundleVendor() != null )
+        {
+            entries.put( BUNDLE_VENDOR, getBundleVendor() );
+        }
+
+        if ( getBundleVersion() != null )
+        {
+            entries.put( BUNDLE_VERSION, getBundleVersion() );
+        }
+
+        if ( getBundleDocUrl() != null )
+        {
+            entries.put( BUNDLE_DOCURL, getBundleDocUrl() );
+        }
+
+        if ( getBundleContactAddress() != null )
+        {
+            entries.put( BUNDLE_CONTACTADDRESS, getBundleContactAddress() );
+        }
+
+        if ( getBundleActivator() != null )
+        {
+            entries.put( BUNDLE_ACTIVATOR, getBundleActivator() );
+        }
+
+        if ( getBundleUpdateLocation() != null )
+        {
+            entries.put( BUNDLE_UPDATELOCATION, getBundleUpdateLocation() );
+        }
+
+        if ( getBundleRequiredExecutionEnvironment() != null )
+        {
+            entries.put( BUNDLE_REQUIREDEXECUTIONENVIRONMENT, getBundleRequiredExecutionEnvironment() );
+        }
+
+        if ( getBundleSymbolicName() != null )
+        {
+            entries.put( BUNDLE_SYMBOLICNAME, getBundleSymbolicName() );
+        }
+
+        if ( getBundleLocalization() != null )
+        {
+            entries.put( BUNDLE_LOCALIZATION, getBundleLocalization() );
+        }
+
+        if ( getRequireBundle() != null )
+        {
+            entries.put( REQUIRE_BUNDLE, getRequireBundle() );
+        }
+
+        if ( getFragmentHost() != null )
+        {
+            entries.put( FRAGMENT_HOST, getFragmentHost() );
+        }
+
+        if ( getBundleManifestVersion() != null )
+        {
+            entries.put( BUNDLE_MANIFESTVERSION, getBundleManifestVersion() );
+        }
+
+        if ( getBundleUrl() != null )
+        {
+            entries.put( BUNDLE_URL, getBundleUrl() );
+        }
+
+        if ( getBundleSource() != null )
+        {
+            entries.put( BUNDLE_SOURCE, getBundleSource() );
+        }
+
+        if ( getBundleDate() != null )
+        {
+            entries.put( BUNDLE_DATE, getBundleDate() );
+        }
+
+        if ( getMetadataLocation() != null )
+        {
+            entries.put( METADATA_LOCATION, getMetadataLocation() );
+        }
+        
+        // iPOJO Headers : 
+        if ( getiPOJOMetadata() != null )
+        {
+            entries.put( IPOJO_METADATA, getiPOJOMetadata() );
+        }
+        
+        if( getiPOJOComponents() != null )
+        {
+        	entries.put( IPOJO_COMPONENTS, getiPOJOComponents() );
+        }
+
+        return entries;
+    }
+
+    public String getBundleCategory()
+    {
+        return bundleCategory;
+    }
+
+    public void setBundleCategory( String bundleCategory )
+    {
+        this.bundleCategory = bundleCategory;
+    }
+
+    /*
+     public String getBundleClasspath()
+     {
+     return bundleClasspath;
+     }
+
+     public void setBundleClasspath(String bundleClasspath)
+     {
+     this.bundleClasspath = bundleClasspath;
+     }
+     */
+
+    public String getBundleCopyright()
+    {
+        return bundleCopyright;
+    }
+
+    public void setBundleCopyright( String bundleCopyright )
+    {
+        this.bundleCopyright = bundleCopyright;
+    }
+
+    public String getBundleDescription()
+    {
+        return bundleDescription;
+    }
+
+    public void setBundleDescription( String bundleDescription )
+    {
+        this.bundleDescription = bundleDescription;
+    }
+
+    public String getBundleName()
+    {
+        return bundleName;
+    }
+
+    public void setBundleName( String bundleName )
+    {
+        this.bundleName = bundleName;
+    }
+
+    public String getBundleNativeCode()
+    {
+        return bundleNativeCode;
+    }
+
+    public void setBundleNativeCode( String bundleNativeCode )
+    {
+        this.bundleNativeCode = bundleNativeCode;
+    }
+
+    public String getExportPackage()
+    {
+        return exportPackage;
+    }
+
+    public void setExportPackage( String exportPackage )
+    {
+        this.exportPackage = exportPackage;
+    }
+
+    public String getExportService()
+    {
+        return exportService;
+    }
+
+    public void setExportService( String exportService )
+    {
+        this.exportService = exportService;
+    }
+
+    public String getImportPackage()
+    {
+        return importPackage;
+    }
+
+    public void setImportPackage( String importPackage )
+    {
+        this.importPackage = importPackage;
+    }
+
+    public String getDynamicImportPackage()
+    {
+        return dynamicImportPackage;
+    }
+
+    public void setDynamicImportPackage( String dynamicImportPackage )
+    {
+        this.dynamicImportPackage = dynamicImportPackage;
+    }
+
+    public String getImportService()
+    {
+        return importService;
+    }
+
+    public void setImportService( String importService )
+    {
+        this.importService = importService;
+    }
+
+    public String getBundleVendor()
+    {
+        return bundleVendor;
+    }
+
+    public void setBundleVendor( String bundleVendor )
+    {
+        this.bundleVendor = bundleVendor;
+    }
+
+    public String getBundleVersion()
+    {
+        return bundleVersion;
+    }
+
+    public void setBundleVersion( String bundleVersion )
+    {
+        this.bundleVersion = bundleVersion;
+    }
+
+    public String getBundleDocUrl()
+    {
+        return bundleDocUrl;
+    }
+
+    public void setBundleDocUrl( String bundleDocUrl )
+    {
+        this.bundleDocUrl = bundleDocUrl;
+    }
+
+    public String getBundleContactAddress()
+    {
+        return bundleContactAddress;
+    }
+
+    public void setBundleContactAddress( String bundleContactAddress )
+    {
+        this.bundleContactAddress = bundleContactAddress;
+    }
+
+    public String getBundleActivator()
+    {
+        return bundleActivator;
+    }
+
+    public void setBundleActivator( String bundleActivator )
+    {
+        this.bundleActivator = bundleActivator;
+    }
+
+    public String getBundleUpdateLocation()
+    {
+        return bundleUpdateLocation;
+    }
+
+    public void setBundleUpdateLocation( String bundleUpdateLocation )
+    {
+        this.bundleUpdateLocation = bundleUpdateLocation;
+    }
+
+    public String getBundleRequiredExecutionEnvironment()
+    {
+        return bundleRequiredExecutionEnvironment;
+    }
+
+    public void setBundleRequiredExecutionEnvironment( String bundleRequiredExecutionEnvironment )
+    {
+        this.bundleRequiredExecutionEnvironment = bundleRequiredExecutionEnvironment;
+    }
+
+    public String getBundleSymbolicName()
+    {
+        return bundleSymbolicName;
+    }
+
+    public void setBundleSymbolicName( String bundleSymbolicName )
+    {
+        this.bundleSymbolicName = bundleSymbolicName;
+    }
+
+    public String getBundleLocalization()
+    {
+        return bundleLocalization;
+    }
+
+    public void setBundleLocalization( String bundleLocalization )
+    {
+        this.bundleLocalization = bundleLocalization;
+    }
+
+    public String getRequireBundle()
+    {
+        return requireBundle;
+    }
+
+    public void setRequireBundle( String requireBundle )
+    {
+        this.requireBundle = requireBundle;
+    }
+
+    public String getFragmentHost()
+    {
+        return fragmentHost;
+    }
+
+    public void setFragmentHost( String fragmentHost )
+    {
+        this.fragmentHost = fragmentHost;
+    }
+
+    public String getBundleManifestVersion()
+    {
+        return bundleManifestVersion;
+    }
+
+    public void setBundleManifestVersion( String bundleManifestVersion )
+    {
+        this.bundleManifestVersion = bundleManifestVersion;
+    }
+
+    public String getBundleUrl()
+    {
+        return bundleUrl;
+    }
+
+    public void setBundleUrl( String bundleUrl )
+    {
+        this.bundleUrl = bundleUrl;
+    }
+
+    public String getBundleSource()
+    {
+        return bundleSource;
+    }
+
+    public void setBundleSource( String bundleSource )
+    {
+        this.bundleSource = bundleSource;
+    }
+
+    public String getBundleDate()
+    {
+        return bundleDate;
+    }
+
+    public void setBundleDate( String bundleDate )
+    {
+        this.bundleDate = bundleDate;
+    }
+
+    public String getMetadataLocation()
+    {
+        return metadataLocation;
+    }
+
+    public void setMetadataLocation( String metadataLocation )
+    {
+        this.metadataLocation = metadataLocation;
+    }
+    
+    // iPOJO Headers
+    public String getiPOJOMetadata() {
+    	return iPOJOMetadata;
+    }
+    
+    public void setiPOJOMetadata( String metadata) {
+    	this.iPOJOMetadata = metadata;
+    }
+    
+    public String getiPOJOComponents() {
+    	return iPOJOComponents;
+    }
+    
+    public void setiPOJOComponents( String metadata) {
+    	this.iPOJOComponents = metadata;
+    }
+}

Propchange: incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/OsgiManifest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/QuotedTokenizer.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/QuotedTokenizer.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/QuotedTokenizer.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/QuotedTokenizer.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,114 @@
+package org.apache.felix.ipojo.plugin;
+
+import java.util.*;
+
+public class QuotedTokenizer {
+	String	string;
+	int		index				= 0;
+	String	separators;
+	boolean	returnTokens;
+	boolean	ignoreWhiteSpace	= true;
+	String	peek;
+	char	separator;
+
+	public QuotedTokenizer(String string, String separators, boolean returnTokens ) {
+		if ( string == null )
+			throw new IllegalArgumentException("string argument must be not null");
+		this.string = string;
+		this.separators = separators;
+		this.returnTokens = returnTokens;
+	}
+	public QuotedTokenizer(String string, String separators) {
+		this(string,separators,false);
+	}
+
+	public String nextToken(String separators) {
+		separator = 0;
+		if ( peek != null ) {
+			String tmp = peek;
+			peek = null;
+			return tmp;
+		}
+		
+		if ( index == string.length())
+			return null;
+		
+		StringBuffer sb = new StringBuffer();
+
+		while (index < string.length()) {
+			char c = string.charAt(index++);
+
+			if ( Character.isWhitespace(c)) {
+				if ( index == string.length())
+					break;
+				else
+					continue;
+			}
+			
+			if (separators.indexOf(c) >= 0) {
+				if (returnTokens)
+					peek = Character.toString(c);
+				else
+					separator = c;
+				break;
+			}
+
+			switch (c) {
+				case '"' :
+				case '\'' :
+					quotedString(sb, c);
+					break;
+
+				default :
+					sb.append(c);
+			}
+		}
+		String result = sb.toString().trim();
+		if ( result.length()==0 && index==string.length())
+			return null;
+		return result;
+	}
+
+	public String nextToken() {
+		return nextToken(separators);
+	}
+
+	private void quotedString(StringBuffer sb, char c) {
+		char quote = c;
+		while (index < string.length()) {
+			c = string.charAt(index++);
+			if (c == quote)
+				break;
+			if (c == '\\' && index < string.length()
+					&& string.charAt(index + 1) == quote)
+				c = string.charAt(index++);
+			sb.append(c);
+		}
+	}
+
+	public String[] getTokens() {
+		return getTokens(0);
+	}
+
+	private String [] getTokens(int cnt){
+		String token = nextToken();
+		if ( token == null ) 
+			return new String[cnt];
+		
+		String result[] = getTokens(cnt+1);
+		result[cnt]=token;
+		return result;
+	}
+
+	public char getSeparator() { return separator; }
+	
+	public List getTokenSet() {
+		List list = new ArrayList();
+		String token = nextToken();
+		while ( token != null ) {
+			list.add(token);
+			token = nextToken();
+		}
+		return list;
+	}
+}

Propchange: incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/QuotedTokenizer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/resources/META-INF/archetype.xml
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/resources/META-INF/archetype.xml?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/resources/META-INF/archetype.xml (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/resources/META-INF/archetype.xml Wed Jun 14 08:22:03 2006
@@ -0,0 +1,9 @@
+<archetype>
+	<id>org.apache.felix.ipojo.plugin</id>
+	<sources>
+		<source>src/main/java/source.txt</source>
+	</sources>
+	<resources>
+		<resource>src/main/resources/metadata.xml</resource>
+	</resources>
+</archetype>
\ No newline at end of file

Propchange: incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/resources/META-INF/archetype.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/resources/META-INF/plexus/components.xml
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/resources/META-INF/plexus/components.xml?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/resources/META-INF/plexus/components.xml (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/resources/META-INF/plexus/components.xml Wed Jun 14 08:22:03 2006
@@ -0,0 +1,40 @@
+<component-set>
+  <components>
+    <component>
+      <role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
+      <role-hint>ipojo-bundle</role-hint>
+      <implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>
+      <configuration>
+        <lifecycles>
+          <lifecycle>
+            <id>default</id>
+            <!-- START SNIPPET: ipojo-bundle-lifecycle -->
+            <phases>
+              <process-resources>org.apache.maven.plugins:maven-resources-plugin:resources</process-resources>
+              <compile>org.apache.maven.plugins:maven-compiler-plugin:compile</compile>
+              <process-test-resources>org.apache.maven.plugins:maven-resources-plugin:testResources</process-test-resources>
+              <test-compile>org.apache.maven.plugins:maven-compiler-plugin:testCompile</test-compile>
+              <test>org.apache.maven.plugins:maven-surefire-plugin:test</test>
+              <package>org.apache.felix:org.apache.felix.ipojo.plugin:ipojo-bundle</package>
+              <install>org.apache.maven.plugins:maven-install-plugin:install</install>
+              <deploy>org.apache.maven.plugins:maven-deploy-plugin:deploy</deploy>
+            </phases>
+            <!-- END SNIPPET: ipojo-bundle-lifecycle -->
+          </lifecycle>
+        </lifecycles>
+      </configuration>
+    </component>
+    <component>
+      <role>org.apache.maven.artifact.handler.ArtifactHandler</role>
+      <role-hint>ipojo-bundle</role-hint>
+      <implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation>
+      <configuration>
+        <type>ipojo-bundle</type>
+        <includesDependencies>true</includesDependencies>
+        <language>java</language>
+        <extension>jar</extension>
+        <addedToClasspath>true</addedToClasspath>
+      </configuration>
+    </component>
+  </components>
+</component-set>

Propchange: incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/resources/META-INF/plexus/components.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/resources/archetype-resources/pom.xml
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/resources/archetype-resources/pom.xml?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/resources/archetype-resources/pom.xml (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/resources/archetype-resources/pom.xml Wed Jun 14 08:22:03 2006
@@ -0,0 +1,33 @@
+<project>
+  <modelVersion>4.0.0</modelVersion>
+  <packaging>ipojo-bundle</packaging>
+  <groupId>${groupId}</groupId>
+  <artifactId>${artifactId}</artifactId>
+  <version>${version}</version>
+  <name>$YOUR_PROJECT_NAME</name>
+  
+  <pluginRepositories>
+    <pluginRepository>
+      <id>iPOJO.repository</id>
+      <name>iPOJO Repository</name>
+      <url>http://www-adele.imag.fr/~escoffie/repository</url>
+    </pluginRepository>
+  </pluginRepositories>
+  
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix.ipojo</groupId>
+        <artifactId>org.apache.felix.ipojo.plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <osgiManifest>
+            <bundleName>${pom.name}</bundleName>
+            <bundleDescription>$YOUR_BUNDLE_DESCRIPTION</bundleDescription>
+            <iPOJOMetadata>metadata.xml</iPOJOMetadata>
+          </osgiManifest>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>

Propchange: incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/resources/archetype-resources/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/resources/archetype-resources/src/main/java/source.txt
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/resources/archetype-resources/src/main/java/source.txt?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/resources/archetype-resources/src/main/java/source.txt (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/resources/archetype-resources/src/main/java/source.txt Wed Jun 14 08:22:03 2006
@@ -0,0 +1 @@
+PUT YOUR SOURCE FILES HERE
\ No newline at end of file

Propchange: incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/resources/archetype-resources/src/main/java/source.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/resources/archetype-resources/src/main/resources/metadata.xml
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/resources/archetype-resources/src/main/resources/metadata.xml?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/resources/archetype-resources/src/main/resources/metadata.xml (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/resources/archetype-resources/src/main/resources/metadata.xml Wed Jun 14 08:22:03 2006
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<iPOJO>
+	<component className="$YOUR_COMPONENT_CLASS">
+   
+	</component>
+</iPOJO>
\ No newline at end of file

Propchange: incubator/felix/trunk/org.apache.felix.ipojo.plugin/src/main/resources/archetype-resources/src/main/resources/metadata.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo/pom.xml
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/pom.xml?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/pom.xml (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/pom.xml Wed Jun 14 08:22:03 2006
@@ -0,0 +1,54 @@
+<project>
+  <parent>
+    <groupId>org.apache.felix</groupId>
+    <artifactId>felix</artifactId>
+    <version>0.8.0-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <packaging>osgi-bundle</packaging>
+  <name>Apache Felix iPOJO</name>
+  <artifactId>org.apache.felix.ipojo</artifactId>
+  <version>0.6.0-SNAPSHOT</version>
+  <dependencies>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <version>0.8.0-SNAPSHOT</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>asm</groupId>
+      <artifactId>asm</artifactId>
+      <version>2.2.1</version>
+    </dependency>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.apache.felix.ipojo.metadata</artifactId>
+      <version>${pom.version}</version>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix.plugins</groupId>
+        <artifactId>maven-osgi-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <osgiManifest>
+            <bundleName>iPOJO</bundleName>
+            <bundleSymbolicName>${pom.artifactId}</bundleSymbolicName>
+            <bundleVendor>Clement ESCOFFIER</bundleVendor>
+            <bundleDescription> iPOJO </bundleDescription>
+            <importPackage>
+              org.osgi.framework, org.osgi.service.cm
+            </importPackage>
+            <exportPackage>
+              org.apache.felix.ipojo, org.apache.felix.ipojo.metadata, org.apache.felix.ipojo.architecture, org.apache.felix.ipojo.parser, org.osgi.service.cm
+            </exportPackage>
+            <bundleActivator>org.apache.felix.ipojo.DummyActivator</bundleActivator>
+          </osgiManifest>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>

Propchange: incubator/felix/trunk/org.apache.felix.ipojo/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/Activator.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/Activator.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/Activator.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/Activator.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,236 @@
+/*
+ *   Copyright 2006 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.felix.ipojo;
+
+
+
+import java.io.IOException;
+import java.util.Dictionary;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.ManifestMetadataParser;
+import org.apache.felix.ipojo.parser.ParseException;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+
+/**
+ * iPOJO generic activator.
+ * Date : 31 mars 2006
+ * @author clement escoffier
+ */
+public class Activator implements BundleActivator {
+
+
+	// STATIC
+	/**
+	 * The iPOJO static logger. This logger is used by each iPOJO instance.
+	 */
+	private static Logger m_logger = Logger.getLogger("org.apache.felix.ipojo");
+
+	 /**
+     * @return Returns the static ipojo logger : org.apache.felix.ipojo
+     */
+    public static Logger getLogger() {
+        return Activator.m_logger;
+    }
+    // END STATIC
+
+    // NON STATIC PART
+
+    /**
+     * The m_bundle context.
+     * m_bundleContext : BundleContext
+     */
+    private BundleContext m_bundleContext = null;
+
+    /**
+     * The component manager for this activator.
+     * m_handler : ComponentManagerFactory
+     */
+    private ComponentManagerFactory[] m_factories;
+
+    // Field accessors  :
+
+    /**
+     * @return the m_bundle context
+     */
+    public BundleContext getBundleContext() {
+        return m_bundleContext;
+    }
+
+    /**
+     * Add a component manager factory to the factory list.
+     * @param cm : the new component metadata.
+     */
+    public void addComponentFactory(Element cm) {
+    	// Create the factory :
+    	ComponentManagerFactory factory = new ComponentManagerFactory(this, cm);
+
+    	// If the factory array is not empty add the new factory at the end
+        if (m_factories.length != 0) {
+            ComponentManagerFactory[] newFactory = new ComponentManagerFactory[m_factories.length + 1];
+            System.arraycopy(m_factories, 0, newFactory, 0, m_factories.length);
+            newFactory[m_factories.length] = factory;
+            m_factories = newFactory;
+        }
+        // Else create an array of size one with the new Factory
+        else { m_factories = new ComponentManagerFactory[] {factory}; }
+    }
+
+    /**
+     * Remove a component manager factory to the factory list.
+     * @param factory : the componet facotry to remove
+     */
+    public void removeComponentFactory(ComponentManagerFactory factory) {
+
+        int idx = -1;
+        for (int i = 0; i < m_factories.length; i++) {
+            if (m_factories[i] == factory) {
+                idx = i;
+                break;
+            }
+        }
+
+        if (idx >= 0) {
+            // If this is the factory, then point to empty list.
+            if ((m_factories.length - 1) == 0) {
+            	m_factories = new ComponentManagerFactory[0];
+            }
+            // Otherwise, we need to do some array copying.
+            else {
+                ComponentManagerFactory[] newFactories = new ComponentManagerFactory[m_factories.length - 1];
+                System.arraycopy(m_factories, 0, newFactories, 0, idx);
+                if (idx < newFactories.length) {
+                    System.arraycopy(m_factories, idx + 1, newFactories, idx, newFactories.length - idx);
+                }
+                m_factories = newFactories;
+            }
+        }
+    }
+
+    // End field accesors
+
+    // Constructors :
+
+    /**
+     * Constructor used by Felix.
+     */
+    public Activator() {
+        super();
+        m_factories = new ComponentManagerFactory[0];
+    }
+
+    // End constuctors
+
+    // Bundle Lifecycle CallBack
+
+    /**
+     * Start method.
+     * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+     * @param bc : the m_bundle context to use to manage the component.
+     * @throws Exception : when a problem occurs
+     */
+    public void start(final BundleContext bc) throws Exception {
+      m_bundleContext = bc;
+
+      // Set the trace level
+      String level = System.getProperty("ipojo.loglevel");
+      if (level != null) {
+         if (level.equals("ALL")) {
+        	 Activator.getLogger().setLevel(Level.ALL);
+         }
+         if (level.equals("FINEST")) {
+        	 Activator.getLogger().setLevel(Level.FINEST);
+         }
+         if (level.equals("WARNING")) {
+        	 Activator.getLogger().setLevel(Level.WARNING);
+         }
+      }
+      else { Activator.getLogger().setLevel(IPojoConfiguration.LOG_LEVEL); }
+
+      try {
+          parse();
+      } catch (Exception e) {
+    	  Activator.getLogger().log(Level.SEVERE, "Parse error for the bundle " + m_bundleContext.getBundle().getBundleId() + " : " + e.getMessage());
+         return;
+      }
+      Activator.getLogger().log(Level.INFO, "[Bundle" + m_bundleContext.getBundle().getBundleId() + "] Called start after the parsing");
+
+      // Call the internal start method
+      start();
+
+    }
+
+    /**
+     * Stop method.
+     * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+     * @param arg0 : the m_bundle context
+     * @throws Exception : ???
+     */
+    public void stop(BundleContext arg0) throws Exception {
+        for (int i = 0; i < m_factories.length; i++) {
+        	ComponentManagerFactory factory = m_factories[i];
+        	factory.stop();
+        }
+    }
+
+    // End Bundle Lifecycle CallBack
+
+    // Parsing methods :
+
+    /**
+     * Parse the file who is at the Metadata-Location place, manipulate the bytecode of the component implementation class
+     * and set the manager.
+     * @throws IOException
+     * @throws ParseException
+     */
+    private void parse() throws IOException, ParseException {
+
+       String componentClasses = (String)m_bundleContext.getBundle().getHeaders().get("iPOJO-Components");
+        if (componentClasses != null) {
+        	parseManifest(m_bundleContext.getBundle().getHeaders());
+        } else {
+        	Activator.getLogger().log(Level.SEVERE, "[Bundle" + m_bundleContext.getBundle().getBundleId() + "] Components-Metadata are not in the manifest");
+        	throw new ParseException("[Bundle" + m_bundleContext.getBundle().getBundleId() + "] Component-Metadata are not in the manifest");
+        }
+    }
+
+    private void parseManifest(Dictionary dict) throws ParseException {
+    	ManifestMetadataParser parser = new ManifestMetadataParser();
+    	parser.parse(dict);
+    	// Create the components Factory according to the declared component
+        Element[] componentsMetadata = parser.getComponentsMetadata();
+        for (int i = 0; i < componentsMetadata.length; i++) {
+        	Activator.getLogger().log(Level.INFO, "[Bundle" + m_bundleContext.getBundle().getBundleId() + "] Create a component factory for " + componentsMetadata[i].getAttribute("classname"));
+        	addComponentFactory(componentsMetadata[i]);
+        }
+    }
+
+    /**
+     * Start the management : Manipulate the classes and start the component manager.
+     */
+    private void start() {
+        for (int i = 0; i < m_factories.length; i++) {
+            ComponentManagerFactory factory = m_factories[i];
+            factory.start(); // Start the management
+        }
+    }
+
+}

Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/Activator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/Callback.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/Callback.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/Callback.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/Callback.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,119 @@
+/*
+ *   Copyright 2006 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.felix.ipojo;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.logging.Level;
+
+
+
+/**
+ * A callback allows calling a method on the component.
+ * @author Clement Escoffier
+ */
+public class Callback {
+
+	/**
+	 * Name of the method to call.
+	 */
+	private String m_method;
+
+	/**
+	 * Is the method a static method ?
+	 */
+	private boolean m_isStatic;
+
+	/**
+	 * Reference on the component manager.
+	 */
+	private ComponentManager m_manager;
+
+	 /**
+     * LifecycleCallback constructor.
+     * @param method : the name of the method to call
+     * @param isStatic : is the method a static method
+     * @param cm : the component manager of the component containing the method
+     */
+    public Callback(String method, boolean isStatic, ComponentManager cm) {
+        m_method = method;
+        m_isStatic = isStatic;
+        m_manager = cm;
+    }
+
+    /**
+     * Call the method.
+     * @throws NoSuchMethodException : Method is not found in the class
+     * @throws InvocationTargetException : The method is not static
+     * @throws IllegalAccessException : The method can not be invoked
+     */
+    public void call() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+    	Activator.getLogger().log(Level.INFO, "[" + m_manager.getComponentMetatada().getClassName() + "] Call an callback method : " + m_method);
+        Method method = m_manager.getClazz().getMethod(m_method, new Class[] {});
+        method.setAccessible(true);
+
+        if (m_isStatic) { method.invoke(null, new Object[]{}); }
+        else {
+        	// Two cases :
+        	// - if instances already exists : call on each instances
+        	// - if no instance exists : create an instance
+        	if (m_manager.getInstances().length == 0) {
+        		Activator.getLogger().log(Level.INFO, "[" + m_manager.getComponentMetatada().getClassName() + "] Create the first instance " + m_manager.getInstance());
+        		method.invoke(m_manager.getInstance(), new Object[]{});
+        	} else {
+        		for (int i = 0; i < m_manager.getInstances().length; i++) {
+            		Activator.getLogger().log(Level.INFO, "[" + m_manager.getComponentMetatada().getClassName() + "] Call the callback on the instance " + m_manager.getInstances()[i]);
+        			method.invoke(m_manager.getInstances()[i], new Object[]{});
+        		}
+        	}
+        }
+    }
+
+    /**
+     * Call the callback on the method with the argument given in parameter.
+     * @param arg : the parameters
+     * @throws NoSuchMethodException : the callback method is not found
+     * @throws IllegalAccessException : the callbback method cannot be called
+     * @throws InvocationTargetException : an error occurs inside the called method
+     */
+    public void call(Object[] arg) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+    	Activator.getLogger().log(Level.INFO, "[" + m_manager.getComponentMetatada().getClassName() + "] Call an callback method : " + m_method);
+
+    	// Build an array of call for arg :
+    	Class[] classes = new Class[arg.length];
+    	for (int i = 0; i < arg.length; i++) {
+    		classes[i] = arg[i].getClass();
+    	}
+        Method method = m_manager.getClazz().getMethod(m_method, classes);
+        method.setAccessible(true);
+
+        if (m_isStatic) { method.invoke(null, arg); }
+        else {
+        	// Two cases :
+        	// - if instances already exists : call on each instances
+        	// - if no instance exists : create an instance
+        	if (m_manager.getInstances().length == 0) {
+        		Activator.getLogger().log(Level.INFO, "[" + m_manager.getComponentMetatada().getClassName() + "] Create the first instance " + m_manager.getInstance());
+        		method.invoke(m_manager.getInstance(), new Object[]{});
+        	} else {
+        		for (int i = 0; i < m_manager.getInstances().length; i++) {
+        			method.invoke(m_manager.getInstances()[i], arg);
+        		}
+        	}
+        }
+    }
+}

Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/Callback.java
------------------------------------------------------------------------------
    svn:eol-style = native