You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cl...@apache.org on 2011/08/18 13:32:22 UTC

svn commit: r1159173 [3/5] - in /felix/trunk/ipojo: ant/ ant/src/main/java/org/apache/felix/ipojo/task/ manipulator/ manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ manipulator/src/main/java/org/apache/felix/ipojo/manipulator/ manipulato...

Added: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/StreamMetadataProvider.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/StreamMetadataProvider.java?rev=1159173&view=auto
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/StreamMetadataProvider.java (added)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/StreamMetadataProvider.java Thu Aug 18 11:32:19 2011
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.manipulator.metadata;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.felix.ipojo.manipulator.MetadataProvider;
+import org.apache.felix.ipojo.manipulator.Reporter;
+import org.apache.felix.ipojo.manipulator.util.Streams;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.xml.parser.ParseException;
+import org.apache.felix.ipojo.xml.parser.SchemaResolver;
+import org.apache.felix.ipojo.xml.parser.XMLMetadataParser;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+/**
+ * A {@code StreamManifestProvider} knows how to load metadata from an InputStream.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class StreamMetadataProvider implements MetadataProvider {
+
+    private InputStream stream;
+
+    private Reporter reporter;
+
+    private boolean validateUsingLocalSchemas = false;
+
+    public StreamMetadataProvider(InputStream stream, Reporter reporter) {
+        this.stream = stream;
+        this.reporter = reporter;
+    }
+
+    /**
+     * Force XML schemas resolution to be performed locally
+     */
+    public void setValidateUsingLocalSchemas(boolean validateUsingLocalSchemas) {
+        this.validateUsingLocalSchemas = validateUsingLocalSchemas;
+    }
+
+    public List<Element> getMetadatas() throws IOException {
+
+        // First time we've been called: parse the XML Stream
+        List<Element> metadata = new ArrayList<Element>();
+
+        try {
+            XMLMetadataParser handler = new XMLMetadataParser();
+
+            XMLReader parser = XMLReaderFactory.createXMLReader();
+            parser.setContentHandler(handler);
+            parser.setFeature("http://xml.org/sax/features/validation", true);
+            parser.setFeature("http://apache.org/xml/features/validation/schema", true);
+            parser.setErrorHandler(handler);
+            if (validateUsingLocalSchemas) {
+                parser.setEntityResolver(new SchemaResolver());
+            }
+
+            // Parse the XML
+            InputSource is = new InputSource(stream);
+            parser.parse(is);
+            Element[] meta = handler.getMetadata();
+
+            // Add parsed metadata
+            if (meta != null) {
+                metadata.addAll(Arrays.asList(meta));
+            }
+
+            // Output a warning message if no metadata was found
+            if (meta == null || meta.length == 0) {
+                reporter.warn("Neither component types, nor instances in the XML metadata");
+            }
+
+        } catch (IOException e) {
+            reporter.error("Cannot open the metadata input stream: " + e.getMessage());
+        } catch (ParseException e) {
+            reporter.error("Parsing error when parsing the XML file: " + e.getMessage());
+        } catch (SAXParseException e) {
+            reporter.error("Error during metadata parsing at line " + e.getLineNumber() + " : " + e.getMessage());
+        } catch (SAXException e) {
+            reporter.error("Parsing error when parsing (Sax Error) the XML file: " + e.getMessage());
+        } finally {
+            Streams.close(stream);
+        }
+
+        return metadata;
+
+    }
+}

Added: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/render/ManipulatedMetadataFilter.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/render/ManipulatedMetadataFilter.java?rev=1159173&view=auto
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/render/ManipulatedMetadataFilter.java (added)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/render/ManipulatedMetadataFilter.java Thu Aug 18 11:32:19 2011
@@ -0,0 +1,59 @@
+/**
+ * JOnAS: Java(TM) Open Application Server
+ * Copyright (C) 2011 Bull S.A.S.
+ * Contact: jonas-team@ow2.org
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ *
+ * --------------------------------------------------------------------------
+ * $Id: $
+ * --------------------------------------------------------------------------
+ */
+
+
+package org.apache.felix.ipojo.manipulator.render;
+
+import org.apache.felix.ipojo.manipulation.MethodCreator;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * A {@code ManipulatedMetadataFilter} is ...
+ *
+ * @author Guillaume Sauthier
+ */
+public class ManipulatedMetadataFilter implements MetadataFilter {
+
+    public boolean accept(Element element) {
+
+        // TODO I'm sure we can do better then testing blindly all attributes
+        // iPOJO manipulated elements filter
+        for (Attribute attribute : element.getAttributes()) {
+            String value = attribute.getValue();
+
+            // Filters:
+            // * manipulated methods
+            // * fields for the InstanceManager
+            // * InstanceManager setter
+            if (value.startsWith(MethodCreator.PREFIX)
+                    || value.contains("org.apache.felix.ipojo.InstanceManager")
+                    || value.contains("_setInstanceManager")) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+}

Added: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/render/MetadataFilter.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/render/MetadataFilter.java?rev=1159173&view=auto
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/render/MetadataFilter.java (added)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/render/MetadataFilter.java Thu Aug 18 11:32:19 2011
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.manipulator.render;
+
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Defines a filter to be tested against Element before rendering them into the Manifest.
+ * If one filter accept the element, the given Element will be filtered, other filters will be ignored.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface MetadataFilter {
+
+    /**
+     * Tests if the given {@link Element} is accepted by the filter.
+     * @param element the tested element.
+     * @return {@literal true} if the filter accept the value (element will
+     *         be omitted from the rendered metadata), {@literal false} otherwise.
+     */
+    public boolean accept(final Element element);
+}

Added: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/render/MetadataRenderer.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/render/MetadataRenderer.java?rev=1159173&view=auto
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/render/MetadataRenderer.java (added)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/render/MetadataRenderer.java Thu Aug 18 11:32:19 2011
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.manipulator.render;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * A {@code MetadataRenderer} renders a given {@link Element} into a String.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class MetadataRenderer {
+
+    private List<MetadataFilter> filters = new ArrayList<MetadataFilter>();
+
+    public MetadataRenderer() {
+        // By default, filter metadata coming from prior manipulation.
+        this.addMetadataFilter(new ManipulatedMetadataFilter());
+    }
+
+    /**
+     * Add a metadata filter
+     * @param filter added filter
+     */
+    public void addMetadataFilter(MetadataFilter filter) {
+        this.filters.add(filter);
+    }
+
+    /**
+     * Generate manipulation metadata.
+     * @param element rendered element.
+     * @return given manipulation metadata + manipulation metadata of the given element.
+     */
+    public String render(Element element) {
+        StringBuilder builder = new StringBuilder();
+        renderElement(element, builder);
+        return builder.toString();
+    }
+
+    private void renderElement(Element element, StringBuilder builder) {
+
+    	// If the element is already here, do not re-add the element.
+        if(!isFiltered(element)) {
+
+            // Print the beginning of the element
+            startElement(element, builder);
+
+            // Render all attributes
+            for (Attribute attribute : element.getAttributes()) {
+                renderAttribute(attribute, builder);
+            }
+
+            // Render child elements
+            for (Element child : element.getElements()) {
+                renderElement(child, builder);
+            }
+
+            // Print the end of the element
+            endElement(builder);
+        }
+
+
+    }
+
+    private void startElement(Element element, StringBuilder builder) {
+        // Default namespace is empty
+        String namespace = "";
+        if (element.getNameSpace() != null) {
+            namespace = element.getNameSpace() + ":";
+        }
+
+        builder.append(namespace)
+                .append(element.getName())
+                .append(" { ");
+    }
+
+    private void endElement(StringBuilder builder) {
+        builder.append("}");
+    }
+
+    private void renderAttribute(Attribute current, StringBuilder builder) {
+
+        // Default namespace is empty
+        String namespace = "";
+        if (current.getNameSpace() != null) {
+            namespace = current.getNameSpace() + ":";
+        }
+
+        // Render the attribute
+        builder.append("$")
+                .append(namespace)
+                .append(current.getName())
+                .append("=")
+                .append(quoted(current.getValue()))
+                .append(" ");
+    }
+
+    private String quoted(String value) {
+        return "\"" + value + "\"";
+    }
+
+    /**
+     * Checks if the given element is an iPOJO generated element from a prior treatment
+     * @param element Element to be tested
+     * @return <code>true</code> if the given element was already injected by iPOJO
+     */
+    private boolean isFiltered(final Element element) {
+
+        // Iterates over all the filters and return the first positive answer (if any)
+        for (MetadataFilter filter : filters) {
+            if (filter.accept(element)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+}

Added: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/reporter/EmptyReporter.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/reporter/EmptyReporter.java?rev=1159173&view=auto
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/reporter/EmptyReporter.java (added)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/reporter/EmptyReporter.java Thu Aug 18 11:32:19 2011
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.manipulator.reporter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.felix.ipojo.manipulator.Reporter;
+import org.apache.felix.ipojo.manipulator.util.Collections5;
+
+/**
+ * An {@code EmptyReporter} is the basis implementation for Reporters.
+ * It is basically a no-op implementation.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class EmptyReporter implements Reporter {
+
+    /**
+     * List of warnings
+     */
+    private List<String> warnings = new ArrayList<String>();
+
+    /**
+     * List of errors
+     */
+    private List<String> errors = new ArrayList<String>();
+
+    public void trace(String message, Object... args) {}
+
+    public void info(String message, Object... args) {}
+
+    public void warn(String message, Object... args) {}
+
+    public void error(String message, Object... args) {}
+
+    public List<String> getErrors() {
+        return errors;
+    }
+
+    public List<String> getWarnings() {
+        return warnings;
+    }
+
+    protected Object[] getMessageArguments(Object... args) {
+        Object[] params = args;
+        if (args != null && args.length > 1) {
+            if (args[args.length - 1] instanceof Throwable) {
+                // last argument is an Exception, remove it
+                params = Collections5.copyOf(args, args.length - 1);
+            }
+        }
+
+        return params;
+    }
+
+    protected Throwable getThrowable(Object... args) {
+        Throwable throwable = null;
+        if (args != null && args.length > 1) {
+            if (args[args.length - 1] instanceof Throwable) {
+                // last argument is an Exception
+                throwable = (Throwable) args[args.length - 1];
+            }
+        }
+        return throwable;
+    }
+}

Added: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/reporter/SystemReporter.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/reporter/SystemReporter.java?rev=1159173&view=auto
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/reporter/SystemReporter.java (added)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/reporter/SystemReporter.java Thu Aug 18 11:32:19 2011
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.manipulator.reporter;
+
+import java.io.PrintStream;
+
+/**
+ * A {@code SystemReporter} reports feedback from within the manipulation process.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class SystemReporter extends EmptyReporter {
+
+    /**
+     * Micro enum used to prefix messages.
+     */
+    private enum Level {
+        TRACE("#"),
+        INFO("I"),
+        WARN("W"),
+        ERROR("E");
+
+        private String value;
+
+        Level(String value) {
+            this.value = value;
+        }
+
+        public String append(String message) {
+            return value + " " + message;
+        }
+    }
+
+    /**
+     * Enable/disable trace logging.
+     */
+    private boolean enableTrace = false;
+
+    public void setEnableTrace(boolean enableTrace) {
+        this.enableTrace = enableTrace;
+    }
+
+    private void log(PrintStream stream, Level level, String formatted, Throwable throwable) {
+        // Print the message
+        stream.println(level.append(formatted));
+
+        // And the exception if any
+        if (throwable != null) {
+            throwable.printStackTrace(stream);
+        }
+    }
+
+    @Override
+    public void trace(String message, Object... args) {
+        if (enableTrace) {
+            String formatted = String.format(message, getMessageArguments(args));
+            log(System.out, Level.TRACE, formatted, getThrowable());
+        }
+    }
+
+    @Override
+    public void info(String message, Object... args) {
+        String formatted = String.format(message, getMessageArguments(args));
+        log(System.out, Level.INFO, formatted, getThrowable());
+    }
+
+    @Override
+    public void warn(String message, Object... args) {
+        String formatted = String.format(message, getMessageArguments(args));
+        Throwable throwable = getThrowable();
+        log(System.out, Level.WARN, formatted, throwable);
+
+        // Append Exception message if any
+        if (throwable != null) {
+            formatted += " ";
+            formatted += throwable.getMessage();
+        }
+        getWarnings().add(formatted);
+    }
+
+    @Override
+    public void error(String message, Object... args) {
+        String formatted = String.format(message, getMessageArguments(args));
+        Throwable throwable = getThrowable();
+        log(System.out, Level.ERROR, formatted, throwable);
+
+        // Append Exception message if any
+        if (throwable != null) {
+            formatted += " ";
+            formatted += throwable.getMessage();
+        }
+        getErrors().add(formatted);
+    }
+
+}

Added: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/DirectoryResourceStore.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/DirectoryResourceStore.java?rev=1159173&view=auto
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/DirectoryResourceStore.java (added)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/DirectoryResourceStore.java Thu Aug 18 11:32:19 2011
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.manipulator.store;
+
+import org.apache.felix.ipojo.manipulator.ResourceStore;
+import org.apache.felix.ipojo.manipulator.ResourceVisitor;
+import org.apache.felix.ipojo.manipulator.store.mapper.FileSystemResourceMapper;
+import org.apache.felix.ipojo.manipulator.store.mapper.IdentityResourceMapper;
+import org.apache.felix.ipojo.manipulator.util.Metadatas;
+import org.apache.felix.ipojo.manipulator.util.Streams;
+import org.apache.felix.ipojo.manipulator.util.Strings;
+import org.apache.felix.ipojo.metadata.Element;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Collections;
+import java.util.jar.Manifest;
+
+/**
+ * A {@link DirectoryResourceStore} knows how to read and write
+ * resources from (to respectively) a File directory.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class DirectoryResourceStore implements ResourceStore {
+
+    /**
+     * Source directory where bytecode is read.
+     */
+    private File source;
+
+    /**
+     * Target directory.
+     */
+    private File target;
+
+    /**
+     * The builder of the updated manifest.
+     */
+    private ManifestBuilder manifestBuilder;
+
+    /**
+     * Original manifest to be updated.
+     */
+    private Manifest manifest;
+
+    /**
+     * Resource Mapper.
+     */
+    private ResourceMapper mapper = new FileSystemResourceMapper(new IdentityResourceMapper());
+
+    public DirectoryResourceStore(File source) {
+        this(source, source);
+    }
+
+    public DirectoryResourceStore(File source, File target) {
+        this.source = source;
+        this.target = target;
+    }
+
+    public void setResourceMapper(ResourceMapper mapper) {
+        this.mapper = new FileSystemResourceMapper(mapper);
+    }
+
+    public void setManifestBuilder(ManifestBuilder manifestBuilder) {
+        this.manifestBuilder = manifestBuilder;
+    }
+
+    public void setManifest(Manifest manifest) {
+        this.manifest = manifest;
+    }
+
+    public byte[] read(String path) throws IOException {
+        File resource = new File(source, mapper.internalize(path));
+        if (!resource.isFile()) {
+            throw new IOException("File '" + resource + "' is not found (for class " + path + ").");
+        }
+        return Streams.readBytes(new FileInputStream(resource));
+    }
+
+    public void accept(ResourceVisitor visitor) {
+        traverseDirectory(source, visitor);
+    }
+
+    private void traverseDirectory(File directory, ResourceVisitor visitor) {
+        for (File child : directory.listFiles()) {
+            if (child.isDirectory()) {
+                traverseDirectory(child, visitor);
+            } else {
+                visitor.visit(getRelativeName(child));
+            }
+        }
+    }
+
+    private String getRelativeName(File file) {
+        String relative = file.getPath().substring(source.getPath().length());
+        return mapper.externalize(relative);
+    }
+
+    public void open() throws IOException {
+
+        // Update the manifest
+        Manifest updated = manifestBuilder.build(manifest);
+
+        // Write it on disk
+        File metaInf = new File(target, "META-INF");
+        File resource = new File(metaInf, "MANIFEST.MF");
+        OutputStream os = new FileOutputStream(resource);
+        try {
+            updated.write(os);
+        } finally {
+            Streams.close(os);
+        }
+
+    }
+
+    public void writeMetadata(Element metadata) {
+        manifestBuilder.addMetada(Collections.singletonList(metadata));
+        manifestBuilder.addReferredPackage(Metadatas.findReferredPackages(metadata));
+    }
+
+    public void write(String resourcePath, byte[] bytecode) throws IOException {
+
+        // Internalize the name
+        File resource = new File(target, mapper.internalize(resourcePath));
+
+        // Create intermediate directories if needed
+        if (!resource.getParentFile().exists()) {
+            resource.getParentFile().mkdirs();
+        }
+
+        FileOutputStream fos = new FileOutputStream(resource);
+        try {
+            fos.write(bytecode);
+            fos.flush();
+        } finally {
+            Streams.close(fos);
+        }
+    }
+
+    public void close() throws IOException {
+        // Nothing to do
+    }
+}

Added: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/JarFileResourceStore.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/JarFileResourceStore.java?rev=1159173&view=auto
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/JarFileResourceStore.java (added)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/JarFileResourceStore.java Thu Aug 18 11:32:19 2011
@@ -0,0 +1,220 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.manipulator.store;
+
+import org.apache.felix.ipojo.manipulator.ResourceStore;
+import org.apache.felix.ipojo.manipulator.ResourceVisitor;
+import org.apache.felix.ipojo.manipulator.store.mapper.IdentityResourceMapper;
+import org.apache.felix.ipojo.manipulator.util.Metadatas;
+import org.apache.felix.ipojo.manipulator.util.Streams;
+import org.apache.felix.ipojo.metadata.Element;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+import java.util.zip.ZipEntry;
+
+/**
+ * A {@link JarFileResourceStore} knows how to read and write
+ * resources from (to respectively) a Jar File.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class JarFileResourceStore implements ResourceStore {
+
+    /**
+     * Source Jar.
+     */
+    private JarFile source;
+
+    /**
+     * Target File.
+     */
+    private File target;
+
+    /**
+     * Modified resources.
+     */
+    private Map<String, byte[]> content;
+
+    /**
+     * Resource Mapper.
+     */
+    private ResourceMapper mapper = new IdentityResourceMapper();
+
+    /**
+     * The builder of the updated manifest.
+     */
+    private ManifestBuilder manifestBuilder;
+
+    /**
+     * Original manifest to be updated.
+     */
+    private Manifest manifest;
+
+    /**
+     * Construct a {@link JarFileResourceStore} wrapping the given original bundle,
+     * and configured to output in the given target file.
+     * @param source original Bundle
+     * @param target File where the updated Bundle will be outputted
+     * @throws IOException if there is an error retrieving the Manifest from the original JarFile
+     */
+    public JarFileResourceStore(JarFile source, File target) throws IOException {
+        this.source = source;
+        this.target = target;
+
+        // TODO ensure File is not null and not an existing file/directory
+        this.target = target;
+        if (source != null) {
+            this.manifest = source.getManifest();
+        } else {
+            this.manifest = new Manifest();
+        }
+        this.content = new TreeMap<String, byte[]>();
+    }
+
+    public void setResourceMapper(ResourceMapper mapper) {
+        this.mapper = mapper;
+    }
+
+    public void setManifestBuilder(ManifestBuilder manifestBuilder) {
+        this.manifestBuilder = manifestBuilder;
+    }
+
+    public void setManifest(Manifest manifest) {
+        this.manifest = manifest;
+    }
+
+    public byte[] read(String path) throws IOException {
+        ZipEntry entry = source.getEntry(getInternalPath(path));
+        if (entry == null) {
+            throw new IOException("Jar Entry is not found for class " + path + ".");
+        }
+        return Streams.readBytes(source.getInputStream(entry));
+    }
+
+    private String getInternalPath(String path) {
+        return mapper.internalize(path);
+    }
+
+    public void accept(ResourceVisitor visitor) {
+        List<JarEntry> entries = Collections.list(source.entries());
+        for (JarEntry entry : entries) {
+            String name = entry.getName();
+            if (!name.endsWith("/")) {
+                // Do not visit directories
+                visitor.visit(getExternalName(entry.getName()));
+            }
+        }
+    }
+
+    private String getExternalName(String path) {
+        return mapper.externalize(path);
+    }
+
+    public void open() throws IOException {
+        // Nothing to do
+    }
+
+    public void writeMetadata(Element metadata) {
+        manifestBuilder.addMetada(Collections.singletonList(metadata));
+        manifestBuilder.addReferredPackage(Metadatas.findReferredPackages(metadata));
+    }
+
+    public void write(String resourcePath, byte[] resource) throws IOException {
+        this.content.put(resourcePath, resource);
+    }
+
+    public void close() throws IOException {
+
+        // Update the manifest
+        Manifest updated = manifestBuilder.build(manifest);
+
+        // Create a new Jar file
+        FileOutputStream fos = new FileOutputStream(target);
+        JarOutputStream jos = new JarOutputStream(fos, updated);
+
+        try {
+            // Copy classes and resources
+            List<JarEntry> entries = Collections.list(source.entries());
+            for (JarEntry entry : entries) {
+
+                // Ignore some entries (MANIFEST, ...)
+                if (isIgnored(entry)) {
+                    continue;
+                }
+
+                if (isUpdated(entry)) {
+                    // Write newer/updated resource (manipulated classes, ...)
+
+                    JarEntry je = new JarEntry(entry.getName());
+                    byte[] data = content.get(getInternalPath(entry.getName()));
+                    jos.putNextEntry(je);
+                    jos.write(data);
+                    jos.closeEntry();
+                } else {
+                    // Copy the resource as-is
+
+                    jos.putNextEntry(entry);
+                    InputStream is = source.getInputStream(entry);
+                    try {
+                        Streams.transfer(is, jos);
+                    } finally {
+                        Streams.close(is);
+                    }
+
+                    jos.closeEntry();
+
+                }
+            }
+        } finally {
+            try {
+                source.close();
+            } catch (IOException e) {
+                // Ignored
+            }
+            Streams.close(jos, fos);
+
+        }
+    }
+
+    private boolean isUpdated(JarEntry entry) {
+        // Check if that class was manipulated
+        if (entry.getName().endsWith(".class")) {
+            // Need to map this into an external+normalized path
+            String cleaned = getExternalName(entry.getName());
+            return content.containsKey(cleaned);
+        } else {
+            return false;
+        }
+    }
+
+    private boolean isIgnored(JarEntry entry) {
+        return "META-INF/MANIFEST.MF".equals(entry.getName());
+    }
+}

Added: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/ManifestBuilder.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/ManifestBuilder.java?rev=1159173&view=auto
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/ManifestBuilder.java (added)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/ManifestBuilder.java Thu Aug 18 11:32:19 2011
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.manipulator.store;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.jar.Manifest;
+
+import org.apache.felix.ipojo.manipulator.render.MetadataFilter;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * A {@code ManifestBuilder} is ...
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface ManifestBuilder {
+    /**
+     * Add all given package names in the referred packages list
+     * @param packageNames additional packages
+     */
+    void addReferredPackage(Set<String> packageNames);
+
+    /**
+     * Add all given metadata
+     * @param metadatas additional metadata
+     */
+    void addMetada(Collection<Element> metadatas);
+
+    /**
+     * Update the given manifest.
+     * @param original original manifest to be modified
+     * @return modified manifest
+     */
+    Manifest build(Manifest original);
+}

Added: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/ResourceMapper.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/ResourceMapper.java?rev=1159173&view=auto
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/ResourceMapper.java (added)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/ResourceMapper.java Thu Aug 18 11:32:19 2011
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.manipulator.store;
+
+/**
+ * A {@code ResourceMapper} maps resource name from a reference to another one.
+ * Example: In a WAB, class names are to be mapped into {@literal WEB-INF/classes/}.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface ResourceMapper {
+
+    /**
+     * Adapts the normalized resource name into internal format.
+     * @param name original class names (as a resource)
+     * @return the transformed resource's name
+     */
+    String internalize(String name);
+
+    /**
+     * Provides a normalized resource name from the store's internal format.
+     * @param name resource name in internal format
+     * @return normalized resource name
+     */
+    String externalize(String name);
+}

Added: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/builder/DefaultManifestBuilder.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/builder/DefaultManifestBuilder.java?rev=1159173&view=auto
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/builder/DefaultManifestBuilder.java (added)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/builder/DefaultManifestBuilder.java Thu Aug 18 11:32:19 2011
@@ -0,0 +1,260 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.manipulator.store.builder;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+import org.apache.felix.ipojo.manipulator.Pojoization;
+import org.apache.felix.ipojo.manipulator.QuotedTokenizer;
+import org.apache.felix.ipojo.manipulator.render.MetadataRenderer;
+import org.apache.felix.ipojo.manipulator.store.ManifestBuilder;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * A {@code DefaultManifestBuilder} handles the knowledge of iPOJO Manifest building.
+ * It is responsible to update a given Manifest with all gathered (additional)
+ * referenced packages (from the metadata.xml) + other iPOJO specific additions.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class DefaultManifestBuilder implements ManifestBuilder {
+
+    /**
+     * Referenced packages (by the composites).
+     */
+    private List<String> m_referredPackages = new ArrayList<String>();
+
+    /**
+     * Computed metadatas from the bundle (XML files + annotations).
+     */
+    private List<Element> m_metadata = new ArrayList<Element>();
+
+    /**
+     * The metadata renderer used to print Elements.
+     */
+    private MetadataRenderer renderer;
+
+    /**
+     * Add all given package names in the referred packages list
+     * @param packageNames additional packages
+     */
+    public void addReferredPackage(Set<String> packageNames) {
+        m_referredPackages.addAll(packageNames);
+    }
+
+    /**
+     * Add all given metadata
+     * @param metadatas additional metadata
+     */
+    public void addMetada(Collection<Element> metadatas) {
+        m_metadata.addAll(metadatas);
+    }
+
+    public void setMetadataRenderer(MetadataRenderer renderer) {
+        this.renderer = renderer;
+    }
+
+    /**
+     * Update the given manifest.
+     * @param original original manifest to be modified
+     * @return modified manifest
+     */
+    public Manifest build(final Manifest original) {
+        Attributes att = original.getMainAttributes();
+
+         // Set the imports (add ipojo and handler namespaces
+        setImports(att);
+         // Add iPOJO-Component
+        setPOJOMetadata(att);
+         // Add iPOJO to the creators
+        setCreatedBy(att);
+
+        return original;
+    }
+
+    /**
+     * Add imports to the given manifest attribute list. This method add ipojo imports and handler imports (if needed).
+     * @param att : the manifest attribute list to modify.
+     */
+    private void setImports(Attributes att) {
+        Map imports = parseHeader(att.getValue("Import-Package"));
+        Map ver = new TreeMap();
+        ver.put("version", Pojoization.IPOJO_PACKAGE_VERSION);
+        if (!imports.containsKey("org.apache.felix.ipojo")) {
+            imports.put("org.apache.felix.ipojo", ver);
+        }
+        if (!imports.containsKey("org.apache.felix.ipojo.architecture")) {
+            imports.put("org.apache.felix.ipojo.architecture", ver);
+        }
+        if (!imports.containsKey("org.osgi.service.cm")) {
+            Map verCM = new TreeMap();
+            verCM.put("version", "1.2");
+            imports.put("org.osgi.service.cm", verCM);
+        }
+        if (!imports.containsKey("org.osgi.service.log")) {
+            Map verCM = new TreeMap();
+            verCM.put("version", "1.3");
+            imports.put("org.osgi.service.log", verCM);
+        }
+
+        // Add referred imports from the metadata
+        for (int i = 0; i < m_referredPackages.size(); i++) {
+            String pack = m_referredPackages.get(i);
+            imports.put(pack, new TreeMap());
+        }
+
+        // Write imports
+        att.putValue("Import-Package", printClauses(imports, "resolution:"));
+    }
+
+    /**
+     * Add iPOJO-Components to the given manifest attribute list. This method add the
+     * {@literal iPOJO-Components} header and its value (according to the metadata)
+     * to the manifest.
+     * @param att the manifest attribute list to modify.
+     */
+    private void setPOJOMetadata(Attributes att) {
+        StringBuilder meta = new StringBuilder();
+        for (Element metadata : m_metadata) {
+            meta.append(renderer.render(metadata));
+        }
+        if (meta.length() != 0) {
+            att.putValue("iPOJO-Components", meta.toString());
+        }
+    }
+
+    /**
+     * Set the create-by in the manifest.
+     * @param att : manifest attribute.
+     */
+    private void setCreatedBy(Attributes att) {
+        String prev = att.getValue("Created-By");
+        if (prev == null) {
+            att.putValue("Created-By", "iPOJO " + Pojoization.IPOJO_PACKAGE_VERSION);
+        } else {
+            if (prev.indexOf("iPOJO") == -1) {
+                // Avoid appending iPOJO several times
+                att.putValue("Created-By", prev + " & iPOJO " + Pojoization.IPOJO_PACKAGE_VERSION);
+            }
+        }
+    }
+
+    /**
+     * Standard OSGi header parser. This parser can handle the format
+     * <pre>
+     * clauses ::= clause ( ',' clause ) +
+     * clause ::= name ( ';' name ) (';' key '=' value )
+     * </pre>
+     * This is mapped to a Map { name => Map { attr|directive => value } }
+     *
+     * @param value String to parse.
+     * @return parsed map.
+     */
+    private Map parseHeader(String value) {
+        if (value == null || value.trim().length() == 0) {
+            return new HashMap();
+        }
+
+        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 ((del = qt.getSeparator()) != '=') {
+                    if (hadAttribute) {
+                        throw new IllegalArgumentException("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;
+    }
+
+    /**
+     * Print a standard Map based OSGi header.
+     *
+     * @param exports : map { name => Map { attribute|directive => value } }
+     * @param allowedDirectives list of allowed directives.
+     * @return the clauses
+     */
+    private String printClauses(Map exports, String allowedDirectives) {
+        StringBuffer sb = new StringBuffer();
+        String del = "";
+
+        for (Iterator i = exports.entrySet().iterator(); i.hasNext();) {
+            Map.Entry entry = (Map.Entry) i.next();
+            String name = (String) entry.getKey();
+            Map map = (Map) entry.getValue();
+            sb.append(del);
+            sb.append(name);
+
+            for (Iterator j = map.entrySet().iterator(); j.hasNext();) {
+                Map.Entry entry2 = (Map.Entry) j.next();
+                String key = (String) entry2.getKey();
+
+                // Skip directives we do not recognize
+                if (key.endsWith(":") && allowedDirectives.indexOf(key) < 0) {
+                    continue;
+                }
+
+                String value = (String) entry2.getValue();
+                sb.append(";");
+                sb.append(key);
+                sb.append("=");
+                boolean dirty = value.indexOf(',') >= 0 || value.indexOf(';') >= 0;
+                if (dirty) {
+                    sb.append("\"");
+                }
+                sb.append(value);
+                if (dirty) {
+                    sb.append("\"");
+                }
+            }
+            del = ", ";
+        }
+        return sb.toString();
+    }
+
+
+
+}

Added: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/mapper/FileSystemResourceMapper.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/mapper/FileSystemResourceMapper.java?rev=1159173&view=auto
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/mapper/FileSystemResourceMapper.java (added)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/mapper/FileSystemResourceMapper.java Thu Aug 18 11:32:19 2011
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.manipulator.store.mapper;
+
+import org.apache.felix.ipojo.manipulator.store.ResourceMapper;
+import org.apache.felix.ipojo.manipulator.util.Strings;
+
+import java.io.File;
+
+/**
+ * ResourceMapper mapping from and to system specific path..
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class FileSystemResourceMapper implements ResourceMapper {
+
+    private ResourceMapper delegate;
+    private char separator;
+
+    public FileSystemResourceMapper(ResourceMapper delegate) {
+        this(delegate, File.separatorChar);
+    }
+
+    public FileSystemResourceMapper(ResourceMapper delegate, char separator) {
+        this.delegate = delegate;
+        this.separator = separator;
+    }
+
+    public String internalize(String name) {
+        // transform as system path the result of the internalization operation
+        return systemPath(delegate.internalize(name));
+    }
+
+    public String externalize(String name) {
+        // normalize he path before giving it to the delegate mapper
+        return delegate.externalize(normalizePath(name));
+    }
+
+    /**
+     * Normalize the given path. Normalization simply replace any
+     * File separator (system dependant) with {@literal '/'}.
+     * @param path system path
+     * @return normalized path
+     */
+    private String normalizePath(String path) {
+        return path.replace(separator, '/');
+    }
+
+    /**
+     * Return a system path from the given normalized path.
+     * @param path normalized path
+     * @return system path
+     */
+    private String systemPath(String path) {
+        return path.replace('/', separator);
+    }
+
+
+}

Added: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/mapper/IdentityResourceMapper.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/mapper/IdentityResourceMapper.java?rev=1159173&view=auto
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/mapper/IdentityResourceMapper.java (added)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/mapper/IdentityResourceMapper.java Thu Aug 18 11:32:19 2011
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.manipulator.store.mapper;
+
+import org.apache.felix.ipojo.manipulator.store.ResourceMapper;
+
+/**
+ * Identity mapper.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class IdentityResourceMapper implements ResourceMapper {
+    public String internalize(String name) {
+        return name;
+    }
+
+    public String externalize(String name) {
+        return name;
+    }
+}

Added: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/mapper/WABResourceMapper.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/mapper/WABResourceMapper.java?rev=1159173&view=auto
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/mapper/WABResourceMapper.java (added)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/mapper/WABResourceMapper.java Thu Aug 18 11:32:19 2011
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.manipulator.store.mapper;
+
+import org.apache.felix.ipojo.manipulator.store.ResourceMapper;
+
+/**
+ * A {@code WABResourceMapper} knows how to map resource names for a Web Application Bundle (WAB).
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ *
+ * TODO It is not actually used by default, that will probably lead to some Exception
+ */
+public class WABResourceMapper implements ResourceMapper {
+
+    public static final String WEB_INF_CLASSES = "WEB-INF/classes/";
+
+    public String internalize(String name) {
+        return WEB_INF_CLASSES + name;
+    }
+
+    public String externalize(String name) {
+        if (name.startsWith(WEB_INF_CLASSES)) {
+            return name.substring(WEB_INF_CLASSES.length());
+        } else {
+            throw new IllegalArgumentException("Path '" + name + "' do not start with '" + WEB_INF_CLASSES + "'");
+        }
+    }
+}

Added: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/util/Collections5.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/util/Collections5.java?rev=1159173&view=auto
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/util/Collections5.java (added)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/util/Collections5.java Thu Aug 18 11:32:19 2011
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.manipulator.util;
+
+import java.lang.reflect.Array;
+
+/**
+ * {@code Collections5} is a static collection of methods being part of the Java6 Collections class.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Collections5 {
+
+    /**
+     * Copies the specified array, truncating or padding with nulls (if necessary)
+     * so the copy has the specified length.  For all indices that are
+     * valid in both the original array and the copy, the two arrays will
+     * contain identical values.  For any indices that are valid in the
+     * copy but not the original, the copy will contain <tt>null</tt>.
+     * Such indices will exist if and only if the specified length
+     * is greater than that of the original array.
+     * The resulting array is of exactly the same class as the original array.
+     *
+     * @param original the array to be copied
+     * @param newLength the length of the copy to be returned
+     * @return a copy of the original array, truncated or padded with nulls
+     *     to obtain the specified length
+     * @throws NegativeArraySizeException if <tt>newLength</tt> is negative
+     * @throws NullPointerException if <tt>original</tt> is null
+     * @since 1.6
+     */
+    public static <T> T[] copyOf(T[] original, int newLength) {
+        return (T[]) copyOf(original, newLength, original.getClass());
+    }
+
+    /**
+     * Copies the specified array, truncating or padding with nulls (if necessary)
+     * so the copy has the specified length.  For all indices that are
+     * valid in both the original array and the copy, the two arrays will
+     * contain identical values.  For any indices that are valid in the
+     * copy but not the original, the copy will contain <tt>null</tt>.
+     * Such indices will exist if and only if the specified length
+     * is greater than that of the original array.
+     * The resulting array is of the class <tt>newType</tt>.
+     *
+     * @param original the array to be copied
+     * @param newLength the length of the copy to be returned
+     * @param newType the class of the copy to be returned
+     * @return a copy of the original array, truncated or padded with nulls
+     *     to obtain the specified length
+     * @throws NegativeArraySizeException if <tt>newLength</tt> is negative
+     * @throws NullPointerException if <tt>original</tt> is null
+     * @throws ArrayStoreException if an element copied from
+     *     <tt>original</tt> is not of a runtime type that can be stored in
+     *     an array of class <tt>newType</tt>
+     * @since 1.6
+     */
+    public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
+        T[] copy = ((Object) newType == (Object) Object[].class)
+            ? (T[]) new Object[newLength]
+            : (T[]) Array.newInstance(newType.getComponentType(), newLength);
+        System.arraycopy(original, 0, copy, 0,
+                         Math.min(original.length, newLength));
+        return copy;
+    }
+}

Added: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/util/Metadatas.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/util/Metadatas.java?rev=1159173&view=auto
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/util/Metadatas.java (added)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/util/Metadatas.java Thu Aug 18 11:32:19 2011
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.manipulator.util;
+
+import org.apache.felix.ipojo.metadata.Element;
+
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * {@code Streams} is a utility class that helps to manipulate streams.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Metadatas {
+
+    /**
+     * Utility class: no public constructor
+     */
+    private Metadatas() {}
+
+    /**
+     * Return the {@literal classname} attribute value.
+     * @param meta metadata to be explored
+     * @return the {@literal classname} attribute value or {@literal null} if
+     *         the attribute does not exists.
+     */
+    public static String getComponentType(Element meta) {
+        return meta.getAttribute("classname");
+    }
+
+    /**
+     * Looks for 'field' attribute in the given metadata.
+     * @param fields discovered fields (accumulator)
+     * @param metadata metadata to inspect
+     */
+    public static void findFields(List<String> fields, Element metadata) {
+        String field = metadata.getAttribute("field");
+        if (field != null && !fields.contains(field)) {
+            fields.add(field);
+        }
+        for (Element element : metadata.getElements()) {
+            findFields(fields, element);
+        }
+    }
+
+    /**
+     * Get packages referenced by component.
+     * @param metadata Element base for the search
+     * @return the Set of referenced packages.
+     */
+    public static Set<String> findReferredPackages(Element metadata) {
+
+        Set<String> packages = new HashSet<String>();
+        Set<String> specifications = findAttributes(metadata, "specification");
+
+        // Extract the package name from each specification (aka interface)
+        for (String specification : specifications) {
+            String name = getPackageName(specification);
+            if (name != null) {
+                packages.add(name);
+            }
+        }
+
+        return packages;
+    }
+
+    private static String getPackageName(String specification) {
+        int last = specification.lastIndexOf('.');
+        if (last != -1) {
+            return specification.substring(0, last);
+        }
+        return null;
+    }
+
+    /**
+     * Find all the values of the specified attribute in the given element.
+     * @param metadata Element to be traversed
+     * @param attributeName Search attribute name
+     * @return Set of attribute values (no duplicate).
+     */
+    public static Set<String> findAttributes(Element metadata, String attributeName) {
+        Set<String> referred = new HashSet<String>();
+
+        // Search in the given element
+        if (metadata.containsAttribute(attributeName)) {
+            referred.add(metadata.getAttribute(attributeName));
+        }
+
+        // Search in children
+        for (Element elem : metadata.getElements()) {
+            Set<String> found = findAttributes(elem, attributeName);
+            referred.addAll(found);
+        }
+
+        // Return all found values
+        return referred;
+    }
+
+
+
+}

Added: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/util/Streams.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/util/Streams.java?rev=1159173&view=auto
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/util/Streams.java (added)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/util/Streams.java Thu Aug 18 11:32:19 2011
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.manipulator.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * {@code Streams} is a utility class that helps to manipulate streams.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Streams {
+
+    private static final int ONE_HUNDRED_KB = 102400;
+
+    private static final int FOUR_KB = 4096;
+
+    /**
+     * Utility class: no public constructor
+     */
+    private Streams() {}
+
+    /**
+     * Close all the streams
+     * @param streams Streams to be closed
+     */
+    public static void close(Closeable... streams) {
+        for (Closeable stream : streams) {
+            if (stream != null) {
+                try {
+                    stream.close();
+                } catch (IOException e) {
+                    // Ignored
+                }
+            }
+        }
+    }
+
+    /**
+     * Transfer the given {@link InputStream} content in the given {@link OutputStream}.
+     * @param is input
+     * @param os output
+     * @throws IOException if there is a transfer error.
+     */
+    public static void transfer(InputStream is, OutputStream os) throws IOException {
+        int read;
+        byte[] buffer = new byte[FOUR_KB];
+        while ((read = is.read(buffer)) != -1) {
+            os.write(buffer, 0, read);
+        }
+    }
+
+    /**
+     * Read the content of the given InputStream as a byte array.
+     * Notice that this method automatically closes the InputStream
+     * @param is source
+     * @return the content of the InputStream
+     * @throws IOException if stream's content cannot be read/written
+     */
+    public static byte[] readBytes(final InputStream is) throws IOException {
+        try {
+            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+
+            int read;
+            byte[] data = new byte[ONE_HUNDRED_KB];
+
+            while ((read = is.read(data, 0, data.length)) != -1) {
+                buffer.write(data, 0, read);
+            }
+
+            buffer.flush();
+
+            return buffer.toByteArray();
+        } finally {
+            close(is);
+        }
+
+    }
+
+}

Added: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/util/Strings.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/util/Strings.java?rev=1159173&view=auto
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/util/Strings.java (added)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/util/Strings.java Thu Aug 18 11:32:19 2011
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.manipulator.util;
+
+import java.io.File;
+
+/**
+ * {@code Strings} is a utility class that helps to manipulate String.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Strings {
+
+    /**
+     * Utility class: no public constructor
+     */
+    private Strings() {}
+
+    /**
+     * Transform a FQN of a class (format {@literal org.objectweb.asm.Visitor}) into
+     * a normalized resource name ({@literal org/objectweb/asm/Visitor.class}).
+     * @param classname FQN of a class to be transformed
+     * @return resource name
+     */
+    public static String asResourcePath(String classname) {
+        return classname.replace('.', '/').concat(".class");
+    }
+
+    /**
+     * Transform a normalized resource path ({@literal org/objectweb/asm/Visitor.class}) into
+     * a fully qualified class name (format {@literal org.objectweb.asm.Visitor}).
+     * @param path normalized resource path to be transformed
+     * @return class name
+     */
+    public static String asClassName(String path) {
+        String transformed = path.replace('/', '.');
+        return transformed.substring(0, transformed.length() - ".class".length());
+    }
+}

Added: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/visitor/ManipulationAdapter.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/visitor/ManipulationAdapter.java?rev=1159173&view=auto
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/visitor/ManipulationAdapter.java (added)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/visitor/ManipulationAdapter.java Thu Aug 18 11:32:19 2011
@@ -0,0 +1,51 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.manipulator.visitor;
+
+import org.apache.felix.ipojo.manipulator.ManipulationResultVisitor;
+import org.apache.felix.ipojo.manipulator.ManipulationVisitor;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Empty ManipulationVisitor visitor.
+ * It is useful to extends this class to keep a working visitor chain.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ManipulationAdapter implements ManipulationVisitor {
+
+    private ManipulationVisitor delegate;
+
+    public ManipulationAdapter(ManipulationVisitor delegate) {
+        this.delegate = delegate;
+    }
+
+    public ManipulationResultVisitor visitManipulationResult(Element metadata) {
+        return new ManipulationResultAdapter(delegate.visitManipulationResult(metadata));
+    }
+
+    public void visitMetadata(Element metadata) {
+        delegate.visitMetadata(metadata);
+    }
+
+    public void visitEnd() {
+        delegate.visitEnd();
+    }
+}

Added: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/visitor/ManipulationResultAdapter.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/visitor/ManipulationResultAdapter.java?rev=1159173&view=auto
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/visitor/ManipulationResultAdapter.java (added)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/visitor/ManipulationResultAdapter.java Thu Aug 18 11:32:19 2011
@@ -0,0 +1,50 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.manipulator.visitor;
+
+import org.apache.felix.ipojo.manipulator.ManipulationResultVisitor;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Empty ManipulationResultVisitor visitor.
+ * It is useful to extends this class to keep a working visitor chain.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ManipulationResultAdapter implements ManipulationResultVisitor {
+
+    private ManipulationResultVisitor delegate;
+
+    public ManipulationResultAdapter(ManipulationResultVisitor delegate) {
+        this.delegate = delegate;
+    }
+
+    public void visitClassStructure(Element structure) {
+        delegate.visitClassStructure(structure);
+    }
+
+    public void visitManipulatedResource(String type, byte[] resource) {
+        delegate.visitManipulatedResource(type, resource);
+    }
+
+    public void visitEnd() {
+        delegate.visitEnd();
+    }
+}

Added: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/visitor/check/CheckFieldConsistencyResultVisitor.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/visitor/check/CheckFieldConsistencyResultVisitor.java?rev=1159173&view=auto
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/visitor/check/CheckFieldConsistencyResultVisitor.java (added)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/visitor/check/CheckFieldConsistencyResultVisitor.java Thu Aug 18 11:32:19 2011
@@ -0,0 +1,104 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.manipulator.visitor.check;
+
+import org.apache.felix.ipojo.manipulator.ManipulationResultVisitor;
+import org.apache.felix.ipojo.manipulator.Reporter;
+import org.apache.felix.ipojo.manipulator.util.Metadatas;
+import org.apache.felix.ipojo.manipulator.visitor.ManipulationResultAdapter;
+import org.apache.felix.ipojo.metadata.Element;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This visitor checks that field referenced in the metadata are present in the bytecode.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class CheckFieldConsistencyResultVisitor extends ManipulationResultAdapter {
+
+    /**
+     * Component's metadata.
+     */
+    private Element metadata;
+
+    /**
+     * Reporter for errors.
+     */
+    private Reporter reporter;
+
+    public CheckFieldConsistencyResultVisitor(ManipulationResultVisitor visitor) {
+        super(visitor);
+    }
+
+    public void setMetadata(Element metadata) {
+        this.metadata = metadata;
+    }
+
+    public void setReporter(Reporter reporter) {
+        this.reporter = reporter;
+    }
+
+    public void visitClassStructure(Element structure) {
+
+        List<String> fieldsInStructure = new ArrayList<String>();
+        collectStructuralFields(fieldsInStructure, structure);
+
+        List<String> fieldsInMetadata = new ArrayList<String>();
+        Metadatas.findFields(fieldsInMetadata, metadata);
+
+        checkReferredFieldsAreInStructure(fieldsInMetadata, fieldsInStructure);
+
+        // Do this at the end because the writer insert the manipulation
+        // metadata inside the component Element
+        // So to avoid duplicate find, we need to execute this code at the end
+        super.visitClassStructure(structure);
+
+    }
+
+    private void collectStructuralFields(List<String> fieldsInStructure, Element structure) {
+        Element[] fields = structure.getElements("field");
+        if (fields != null) {
+            for (Element field : fields) {
+                fieldsInStructure.add(field.getAttribute("name"));
+            }
+        }
+    }
+
+    /**
+     * Detects missing fields.
+     * If a referenced field does not exist in the class
+     * the method throws an error breaking the build process.
+     * @param fieldsInMetadata
+     * @param fieldsInStructure
+     */
+    private void checkReferredFieldsAreInStructure(List<String> fieldsInMetadata, List<String> fieldsInStructure) {
+        // Then, try to find each referred field in the given field map
+        for (String fieldName : fieldsInMetadata) {
+            if (!fieldsInStructure.contains(fieldName)) {
+                reporter.error("The field " + fieldName + " is referenced in the "
+                        + "metadata but does not exist in the " + Metadatas.getComponentType(metadata)
+                        + " class");
+            }
+        }
+    }
+
+}

Added: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/visitor/check/CheckFieldConsistencyVisitor.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/visitor/check/CheckFieldConsistencyVisitor.java?rev=1159173&view=auto
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/visitor/check/CheckFieldConsistencyVisitor.java (added)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/visitor/check/CheckFieldConsistencyVisitor.java Thu Aug 18 11:32:19 2011
@@ -0,0 +1,52 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.manipulator.visitor.check;
+
+import org.apache.felix.ipojo.manipulator.ManipulationResultVisitor;
+import org.apache.felix.ipojo.manipulator.ManipulationVisitor;
+import org.apache.felix.ipojo.manipulator.Reporter;
+import org.apache.felix.ipojo.manipulator.visitor.ManipulationAdapter;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Execute field verification.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class CheckFieldConsistencyVisitor extends ManipulationAdapter {
+
+    private Reporter reporter;
+
+    public CheckFieldConsistencyVisitor(ManipulationVisitor visitor) {
+        super(visitor);
+    }
+
+    public void setReporter(Reporter reporter) {
+        this.reporter = reporter;
+    }
+
+    public ManipulationResultVisitor visitManipulationResult(Element metadata) {
+        CheckFieldConsistencyResultVisitor rv = new CheckFieldConsistencyResultVisitor(super.visitManipulationResult(metadata));
+        rv.setMetadata(metadata);
+        rv.setReporter(reporter);
+        return rv;
+    }
+
+}

Added: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/visitor/writer/ManipulatedResourcesWriter.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/visitor/writer/ManipulatedResourcesWriter.java?rev=1159173&view=auto
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/visitor/writer/ManipulatedResourcesWriter.java (added)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/visitor/writer/ManipulatedResourcesWriter.java Thu Aug 18 11:32:19 2011
@@ -0,0 +1,81 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.manipulator.visitor.writer;
+
+import org.apache.felix.ipojo.manipulator.ManipulationResultVisitor;
+import org.apache.felix.ipojo.manipulator.ManipulationVisitor;
+import org.apache.felix.ipojo.manipulator.Reporter;
+import org.apache.felix.ipojo.manipulator.ResourceStore;
+import org.apache.felix.ipojo.metadata.Element;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Write manipulation result in the backend (store).
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ManipulatedResourcesWriter implements ManipulationVisitor {
+
+    private ResourceStore resourceStore;
+    private Reporter reporter;
+    private List<ManipulatedResultWriter> writers;
+
+    public ManipulatedResourcesWriter() {
+        this.writers = new ArrayList<ManipulatedResultWriter>();
+    }
+
+    public void setResourceStore(ResourceStore resourceStore) {
+        this.resourceStore = resourceStore;
+    }
+
+    public void setReporter(Reporter reporter) {
+        this.reporter = reporter;
+    }
+
+    public ManipulationResultVisitor visitManipulationResult(Element metadata) {
+        this.resourceStore.writeMetadata(metadata);
+        ManipulatedResultWriter writer = new ManipulatedResultWriter(metadata);
+        writers.add(writer);
+        return writer;
+    }
+
+    public void visitMetadata(Element metadata) {
+        this.resourceStore.writeMetadata(metadata);
+    }
+
+    public void visitEnd() {
+
+        try {
+            resourceStore.open();
+            for (ManipulatedResultWriter writer : writers) {
+                for (Map.Entry<String, byte[]> entry : writer.getResources().entrySet()) {
+                    resourceStore.write(entry.getKey(), entry.getValue());
+                }
+            }
+            resourceStore.close();
+        } catch (IOException e) {
+            reporter.error("Cannot store manipulation result: " + e.getMessage());
+        }
+    }
+}