You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ace.apache.org by ma...@apache.org on 2013/04/04 11:43:37 UTC

svn commit: r1464402 [5/11] - in /ace/trunk: org.apache.ace.deployment.api/ org.apache.ace.deployment.deploymentadmin/ org.apache.ace.deployment.itest/ org.apache.ace.deployment.itest/src/org/apache/ace/it/deployment/ org.apache.ace.deployment.provider...

Added: ace/trunk/org.apache.ace.verifier/impl.bnd
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.verifier/impl.bnd?rev=1464402&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.verifier/impl.bnd (added)
+++ ace/trunk/org.apache.ace.verifier/impl.bnd Thu Apr  4 09:43:34 2013
@@ -0,0 +1,14 @@
+Export-Package: org.apache.ace.deployment.verifier,\
+	org.osgi.service.log,\
+	org.osgi.framework.wiring
+Private-Package: org.apache.felix.framework,\
+	org.apache.felix.framework.capabilityset,\
+	org.apache.felix.framework.resolver,\
+	org.apache.felix.framework.util,\
+	org.apache.felix.framework.util.manifestparser,\
+	org.apache.felix.framework.wiring,\
+	org.apache.ace.deployment.verifier.impl
+Import-Package: org.osgi.framework;version='[1.5,2)',\
+	*
+Bundle-Version: 1.0.0
+Bundle-Activator: org.apache.ace.deployment.verifier.impl.Activator

Added: ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/VerifierService.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/VerifierService.java?rev=1464402&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/VerifierService.java (added)
+++ ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/VerifierService.java Thu Apr  4 09:43:34 2013
@@ -0,0 +1,57 @@
+/*
+ * 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.ace.deployment.verifier;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.osgi.framework.BundleException;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.service.log.LogEntry;
+
+
+public interface VerifierService {
+	public static final String EE_1_7 = "JavaSE-1.6,JavaSE-1.7,J2SE-1.5,J2SE-1.4,J2SE-1.3,OSGi/Minimum-1.2,OSGi/Minimum-1.1,OSGi/Minimum-1.0";
+	public static final String EE_1_6 = "JavaSE-1.6,J2SE-1.5,J2SE-1.4,J2SE-1.3,OSGi/Minimum-1.2,OSGi/Minimum-1.1,OSGi/Minimum-1.0";
+	public static final String EE_1_5 = "J2SE-1.5,J2SE-1.4,J2SE-1.3,OSGi/Minimum-1.2,OSGi/Minimum-1.1,OSGi/Minimum-1.0";
+	public static final String EE_1_4 = "J2SE-1.4,J2SE-1.3,OSGi/Minimum-1.2,OSGi/Minimum-1.1,OSGi/Minimum-1.0";
+	public static final String EE_1_3 = "J2SE-1.3,OSGi/Minimum-1.1,OSGi/Minimum-1.0";
+	
+	public static final String SYSTEM_PACKAGES = "org.osgi.framework; version=1.5.0,org.osgi.framework.launch; version=1.0.0,org.osgi.framework.hooks.service; version=1.0.0,org.osgi.service.packageadmin; version=1.2.0,org.osgi.service.startlevel; version=1.1.0,org.osgi.service.url; version=1.0.0,org.osgi.util.tracker; version=1.4.0";
+	public static final String JRE_1_3_PACKAGES = "javax.accessibility;javax.naming;javax.naming.directory;javax.naming.event;javax.naming.ldap;javax.naming.spi;javax.rmi;javax.rmi.CORBA;javax.sound.midi;javax.sound.midi.spi;javax.sound.sampled;javax.sound.sampled.spi;javax.swing;javax.swing.border;javax.swing.colorchooser;javax.swing.event;javax.swing.filechooser;javax.swing.plaf;javax.swing.plaf.basic;javax.swing.plaf.metal;javax.swing.plaf.multi;javax.swing.table;javax.swing.text;javax.swing.text.html;javax.swing.text.html.parser;javax.swing.text.rtf;javax.swing.tree;javax.swing.undo;javax.transaction;org.omg.CORBA;org.omg.CORBA_2_3;org.omg.CORBA_2_3.portable;org.omg.CORBA.DynAnyPackage;org.omg.CORBA.ORBPackage;org.omg.CORBA.portable;org.omg.CORBA.TypeCodePackage;org.omg.CosNaming;org.omg.CosNaming.NamingContextPackage;org.omg.SendingContext;org.omg.stub.java.rmi;version=\"0.0.0.1_003_J2SE\"";
+	public static final String JRE_1_4_PACKAGES="javax.accessibility;javax.crypto;javax.crypto.interfaces;javax.crypto.spec;javax.imageio;javax.imageio.event;javax.imageio.metadata;javax.imageio.plugins.jpeg;javax.imageio.spi;javax.imageio.stream;javax.naming;javax.naming.directory;javax.naming.event;javax.naming.ldap;javax.naming.spi;javax.net;javax.net.ssl;javax.print;javax.print.attribute;javax.print.attribute.standard;javax.print.event;javax.rmi;javax.rmi.CORBA;javax.security.auth;javax.security.auth.callback;javax.security.auth.kerberos;javax.security.auth.login;javax.security.auth.spi;javax.security.auth.x500;javax.security.cert;javax.sound.midi;javax.sound.midi.spi;javax.sound.sampled;javax.sound.sampled.spi;javax.sql;javax.swing;javax.swing.border;javax.swing.colorchooser;javax.swing.event;javax.swing.filechooser;javax.swing.plaf;javax.swing.plaf.basic;javax.swing.plaf.metal;javax.swing.plaf.multi;javax.swing.table;javax.swing.text;javax.swing.text.html;javax.swing.text
 .html.parser;javax.swing.text.rtf;javax.swing.tree;javax.swing.undo;javax.transaction;javax.transaction.xa;javax.xml.parsers;javax.xml.transform;javax.xml.transform.dom;javax.xml.transform.sax;javax.xml.transform.stream;org.ietf.jgss;org.omg.CORBA;org.omg.CORBA_2_3;org.omg.CORBA_2_3.portable;org.omg.CORBA.DynAnyPackage;org.omg.CORBA.ORBPackage;org.omg.CORBA.portable;org.omg.CORBA.TypeCodePackage;org.omg.CosNaming;org.omg.CosNaming.NamingContextExtPackage;org.omg.CosNaming.NamingContextPackage;org.omg.Dynamic;org.omg.DynamicAny;org.omg.DynamicAny.DynAnyFactoryPackage;org.omg.DynamicAny.DynAnyPackage;org.omg.IOP;org.omg.IOP.CodecFactoryPackage;org.omg.IOP.CodecPackage;org.omg.Messaging;org.omg.PortableInterceptor;org.omg.PortableInterceptor.ORBInitInfoPackage;org.omg.PortableServer;org.omg.PortableServer.CurrentPackage;org.omg.PortableServer.POAManagerPackage;org.omg.PortableServer.POAPackage;org.omg.PortableServer.portable;org.omg.PortableServer.ServantLocatorPackage;org.omg.
 SendingContext;org.omg.stub.java.rmi;org.w3c.dom;org.w3c.dom.css;org.w3c.dom.events;org.w3c.dom.html;org.w3c.dom.stylesheets;org.w3c.dom.traversal;org.w3c.dom.views;org.xml.sax;org.xml.sax.ext;org.xml.sax.helpers;version=\"0.0.0.1_004_J2SE\"";
+	public static final String JRE_1_5_PACKAGES="javax.accessibility;javax.activity;javax.crypto;javax.crypto.interfaces;javax.crypto.spec;javax.imageio;javax.imageio.event;javax.imageio.metadata;javax.imageio.plugins.bmp;javax.imageio.plugins.jpeg;javax.imageio.spi;javax.imageio.stream;javax.management;javax.management.loading;javax.management.modelmbean;javax.management.monitor;javax.management.openmbean;javax.management.relation;javax.management.remote;javax.management.remote.rmi;javax.management.timer;javax.naming;javax.naming.directory;javax.naming.event;javax.naming.ldap;javax.naming.spi;javax.net;javax.net.ssl;javax.print;javax.print.attribute;javax.print.attribute.standard;javax.print.event;javax.rmi;javax.rmi.CORBA;javax.rmi.ssl;javax.security.auth;javax.security.auth.callback;javax.security.auth.kerberos;javax.security.auth.login;javax.security.auth.spi;javax.security.auth.x500;javax.security.cert;javax.security.sasl;javax.sound.midi;javax.sound.midi.spi;javax.sound.s
 ampled;javax.sound.sampled.spi;javax.sql;javax.sql.rowset;javax.sql.rowset.serial;javax.sql.rowset.spi;javax.swing;javax.swing.border;javax.swing.colorchooser;javax.swing.event;javax.swing.filechooser;javax.swing.plaf;javax.swing.plaf.basic;javax.swing.plaf.metal;javax.swing.plaf.multi;javax.swing.plaf.synth;javax.swing.table;javax.swing.text;javax.swing.text.html;javax.swing.text.html.parser;javax.swing.text.rtf;javax.swing.tree;javax.swing.undo;javax.transaction;javax.transaction.xa;javax.xml;javax.xml.datatype;javax.xml.namespace;javax.xml.parsers;javax.xml.transform;javax.xml.transform.dom;javax.xml.transform.sax;javax.xml.transform.stream;javax.xml.validation;javax.xml.xpath;org.ietf.jgss;org.omg.CORBA;org.omg.CORBA_2_3;org.omg.CORBA_2_3.portable;org.omg.CORBA.DynAnyPackage;org.omg.CORBA.ORBPackage;org.omg.CORBA.portable;org.omg.CORBA.TypeCodePackage;org.omg.CosNaming;org.omg.CosNaming.NamingContextExtPackage;org.omg.CosNaming.NamingContextPackage;org.omg.Dynamic;org.om
 g.DynamicAny;org.omg.DynamicAny.DynAnyFactoryPackage;org.omg.DynamicAny.DynAnyPackage;org.omg.IOP;org.omg.IOP.CodecFactoryPackage;org.omg.IOP.CodecPackage;org.omg.Messaging;org.omg.PortableInterceptor;org.omg.PortableInterceptor.ORBInitInfoPackage;org.omg.PortableServer;org.omg.PortableServer.CurrentPackage;org.omg.PortableServer.POAManagerPackage;org.omg.PortableServer.POAPackage;org.omg.PortableServer.portable;org.omg.PortableServer.ServantLocatorPackage;org.omg.SendingContext;org.omg.stub.java.rmi;org.omg.stub.javax.management.remote.rmi;org.w3c.dom;org.w3c.dom.bootstrap;org.w3c.dom.css;org.w3c.dom.events;org.w3c.dom.html;org.w3c.dom.ls;org.w3c.dom.ranges;org.w3c.dom.stylesheets;org.w3c.dom.traversal;org.w3c.dom.views;org.xml.sax;org.xml.sax.ext;org.xml.sax.helpers;version=\"0.0.0.1_005_J2SE\"";
+	public static final String JRE_1_6_PACKAGES="javax.accessibility;javax.activation;javax.activity;javax.annotation;javax.annotation.processing;javax.crypto;javax.crypto.interfaces;javax.crypto.spec;javax.imageio;javax.imageio.event;javax.imageio.metadata;javax.imageio.plugins.bmp;javax.imageio.plugins.jpeg;javax.imageio.spi;javax.imageio.stream;javax.jws;javax.jws.soap;javax.lang.model;javax.lang.model.element;javax.lang.model.type;javax.lang.model.util;javax.management;javax.management.loading;javax.management.modelmbean;javax.management.monitor;javax.management.openmbean;javax.management.relation;javax.management.remote;javax.management.remote.rmi;javax.management.timer;javax.naming;javax.naming.directory;javax.naming.event;javax.naming.ldap;javax.naming.spi;javax.net;javax.net.ssl;javax.print;javax.print.attribute;javax.print.attribute.standard;javax.print.event;javax.rmi;javax.rmi.CORBA;javax.rmi.ssl;javax.script;javax.security.auth;javax.security.auth.callback;javax.sec
 urity.auth.kerberos;javax.security.auth.login;javax.security.auth.spi;javax.security.auth.x500;javax.security.cert;javax.security.sasl;javax.sound.midi;javax.sound.midi.spi;javax.sound.sampled;javax.sound.sampled.spi;javax.sql;javax.sql.rowset;javax.sql.rowset.serial;javax.sql.rowset.spi;javax.swing;javax.swing.border;javax.swing.colorchooser;javax.swing.event;javax.swing.filechooser;javax.swing.plaf;javax.swing.plaf.basic;javax.swing.plaf.metal;javax.swing.plaf.multi;javax.swing.plaf.synth;javax.swing.table;javax.swing.text;javax.swing.text.html;javax.swing.text.html.parser;javax.swing.text.rtf;javax.swing.tree;javax.swing.undo;javax.tools;javax.transaction;javax.transaction.xa;javax.xml;javax.xml.bind;javax.xml.bind.annotation;javax.xml.bind.annotation.adapters;javax.xml.bind.attachment;javax.xml.bind.helpers;javax.xml.bind.util;javax.xml.crypto;javax.xml.crypto.dom;javax.xml.crypto.dsig;javax.xml.crypto.dsig.dom;javax.xml.crypto.dsig.keyinfo;javax.xml.crypto.dsig.spec;jav
 ax.xml.datatype;javax.xml.namespace;javax.xml.parsers;javax.xml.soap;javax.xml.stream;javax.xml.stream.events;javax.xml.stream.util;javax.xml.transform;javax.xml.transform.dom;javax.xml.transform.sax;javax.xml.transform.stax;javax.xml.transform.stream;javax.xml.validation;javax.xml.ws;javax.xml.ws.handler;javax.xml.ws.handler.soap;javax.xml.ws.http;javax.xml.ws.soap;javax.xml.ws.spi;javax.xml.ws.wsaddressing;javax.xml.xpath;org.ietf.jgss;org.omg.CORBA;org.omg.CORBA_2_3;org.omg.CORBA_2_3.portable;org.omg.CORBA.DynAnyPackage;org.omg.CORBA.ORBPackage;org.omg.CORBA.portable;org.omg.CORBA.TypeCodePackage;org.omg.CosNaming;org.omg.CosNaming.NamingContextExtPackage;org.omg.CosNaming.NamingContextPackage;org.omg.Dynamic;org.omg.DynamicAny;org.omg.DynamicAny.DynAnyFactoryPackage;org.omg.DynamicAny.DynAnyPackage;org.omg.IOP;org.omg.IOP.CodecFactoryPackage;org.omg.IOP.CodecPackage;org.omg.Messaging;org.omg.PortableInterceptor;org.omg.PortableInterceptor.ORBInitInfoPackage;org.omg.Porta
 bleServer;org.omg.PortableServer.CurrentPackage;org.omg.PortableServer.POAManagerPackage;org.omg.PortableServer.POAPackage;org.omg.PortableServer.portable;org.omg.PortableServer.ServantLocatorPackage;org.omg.SendingContext;org.omg.stub.java.rmi;org.omg.stub.javax.management.remote.rmi;org.w3c.dom;org.w3c.dom.bootstrap;org.w3c.dom.css;org.w3c.dom.events;org.w3c.dom.html;org.w3c.dom.ls;org.w3c.dom.ranges;org.w3c.dom.stylesheets;org.w3c.dom.traversal;org.w3c.dom.views;org.w3c.dom.xpath;org.xml.sax;org.xml.sax.ext;org.xml.sax.helpers;version=\"0.0.0.1_006_JavaSE\"";
+	public static final String JRE_1_7_PACKAGES="javax.accessibility;javax.activation;javax.activity;javax.annotation;javax.annotation.processing;javax.crypto;javax.crypto.interfaces;javax.crypto.spec;javax.imageio;javax.imageio.event;javax.imageio.metadata;javax.imageio.plugins.bmp;javax.imageio.plugins.jpeg;javax.imageio.spi;javax.imageio.stream;javax.jws;javax.jws.soap;javax.lang.model;javax.lang.model.element;javax.lang.model.type;javax.lang.model.util;javax.management;javax.management.loading;javax.management.modelmbean;javax.management.monitor;javax.management.openmbean;javax.management.relation;javax.management.remote;javax.management.remote.rmi;javax.management.timer;javax.naming;javax.naming.directory;javax.naming.event;javax.naming.ldap;javax.naming.spi;javax.net;javax.net.ssl;javax.print;javax.print.attribute;javax.print.attribute.standard;javax.print.event;javax.rmi;javax.rmi.CORBA;javax.rmi.ssl;javax.script;javax.security.auth;javax.security.auth.callback;javax.sec
 urity.auth.kerberos;javax.security.auth.login;javax.security.auth.spi;javax.security.auth.x500;javax.security.cert;javax.security.sasl;javax.smartcardio;javax.sound.midi;javax.sound.midi.spi;javax.sound.sampled;javax.sound.sampled.spi;javax.sql;javax.sql.rowset;javax.sql.rowset.serial;javax.sql.rowset.spi;javax.swing;javax.swing.border;javax.swing.colorchooser;javax.swing.event;javax.swing.filechooser;javax.swing.plaf;javax.swing.plaf.basic;javax.swing.plaf.metal;javax.swing.plaf.multi;javax.swing.plaf.nimbus;javax.swing.plaf.synth;javax.swing.table;javax.swing.text;javax.swing.text.html;javax.swing.text.html.parser;javax.swing.text.rtf;javax.swing.tree;javax.swing.undo;javax.tools;javax.transaction;javax.transaction.xa;javax.xml;javax.xml.bind;javax.xml.bind.annotation;javax.xml.bind.annotation.adapters;javax.xml.bind.attachment;javax.xml.bind.helpers;javax.xml.bind.util;javax.xml.crypto;javax.xml.crypto.dom;javax.xml.crypto.dsig;javax.xml.crypto.dsig.dom;javax.xml.crypto.d
 sig.keyinfo;javax.xml.crypto.dsig.spec;javax.xml.datatype;javax.xml.namespace;javax.xml.parsers;javax.xml.soap;javax.xml.stream;javax.xml.stream.events;javax.xml.stream.util;javax.xml.transform;javax.xml.transform.dom;javax.xml.transform.sax;javax.xml.transform.stax;javax.xml.transform.stream;javax.xml.validation;javax.xml.ws;javax.xml.ws.handler;javax.xml.ws.handler.soap;javax.xml.ws.http;javax.xml.ws.soap;javax.xml.ws.spi;javax.xml.ws.spi.http;javax.xml.ws.wsaddressing;javax.xml.xpath;org.ietf.jgss;org.omg.CORBA;org.omg.CORBA.DynAnyPackage;org.omg.CORBA.ORBPackage;org.omg.CORBA.TypeCodePackage;org.omg.CORBA.portable;org.omg.CORBA_2_3;org.omg.CORBA_2_3.portable;org.omg.CosNaming;org.omg.CosNaming.NamingContextExtPackage;org.omg.CosNaming.NamingContextPackage;org.omg.Dynamic;org.omg.DynamicAny;org.omg.DynamicAny.DynAnyFactoryPackage;org.omg.DynamicAny.DynAnyPackage;org.omg.IOP;org.omg.IOP.CodecFactoryPackage;org.omg.IOP.CodecPackage;org.omg.Messaging;org.omg.PortableIntercep
 tor;org.omg.PortableInterceptor.ORBInitInfoPackage;org.omg.PortableServer;org.omg.PortableServer.CurrentPackage;org.omg.PortableServer.POAManagerPackage;org.omg.PortableServer.POAPackage;org.omg.PortableServer.ServantLocatorPackage;org.omg.PortableServer.portable;org.omg.SendingContext;org.omg.stub.java.rmi;org.omg.stub.javax.management.remote.rmi;org.w3c.dom;org.w3c.dom.bootstrap;org.w3c.dom.css;org.w3c.dom.events;org.w3c.dom.html;org.w3c.dom.ls;org.w3c.dom.ranges;org.w3c.dom.stylesheets;org.w3c.dom.traversal;org.w3c.dom.views;org.w3c.dom.xpath;org.xml.sax;org.xml.sax.ext;org.xml.sax.helpers;version=\"0.0.0.1_007_JavaSE\"";
+	
+	public interface VerifyReporter {
+        void reportWire(BundleRevision importer, BundleRequirement reqirement, BundleRevision exporter, BundleCapability capability);
+		void reportLog(LogEntry logEntry);
+		void reportException(Exception ex);
+		
+	}
+	public interface VerifyEnvironment {
+		public BundleRevision addBundle(long id, Map<String, String> manifest) throws BundleException;
+		public boolean verifyResolve(Set<BundleRevision> mandatory, Set<BundleRevision> optional, Set<BundleRevision> ondemandFragments);
+	}
+	
+	public VerifyEnvironment createEnvironment(Map<String, String> config, VerifyReporter reporter);
+}
\ No newline at end of file

Added: ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/impl/Activator.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/impl/Activator.java?rev=1464402&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/impl/Activator.java (added)
+++ ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/impl/Activator.java Thu Apr  4 09:43:34 2013
@@ -0,0 +1,43 @@
+/*
+ * 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.ace.deployment.verifier.impl;
+
+import org.apache.ace.deployment.verifier.VerifierService;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+/**
+ * Provides a {@link BundleActivator} implementation for the {@link VerifierService}.
+ */
+public class Activator implements BundleActivator {
+
+    /**
+     * {@inheritDoc}
+     */
+    public void start(BundleContext context) {
+        context.registerService(VerifierService.class.getName(), new VerifierServiceImpl(), null);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void stop(BundleContext context) {
+        // Nop
+    }
+}

Added: ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/impl/VerifierBundleRevision.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/impl/VerifierBundleRevision.java?rev=1464402&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/impl/VerifierBundleRevision.java (added)
+++ ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/impl/VerifierBundleRevision.java Thu Apr  4 09:43:34 2013
@@ -0,0 +1,214 @@
+/*
+ * 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.ace.deployment.verifier.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.felix.framework.Logger;
+import org.apache.felix.framework.util.manifestparser.ManifestParser;
+import org.apache.felix.framework.util.manifestparser.R4Library;
+import org.apache.felix.framework.wiring.BundleCapabilityImpl;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWiring;
+
+/**
+ *
+ */
+public class VerifierBundleRevision implements BundleRevision {
+    
+	private final String m_symbolicName;
+	private final Version m_version;
+	private final List<BundleCapability> m_declaredCaps;
+	private final List<BundleRequirement> m_declaredReqs;
+	private final int m_type;
+	private final Bundle m_bundle;
+	private final List<R4Library> m_declaredLibs;
+	private final Map<String, String> m_headers;
+
+	/**
+	 * @param log
+	 * @param bundle
+	 * @param config
+	 * @param headers
+	 * @throws BundleException
+	 */
+	public VerifierBundleRevision(Logger log, Bundle bundle, Map<String, String> config, Map<String, String> headers) throws BundleException {
+		m_bundle = bundle;
+		m_headers = Collections.unmodifiableMap(headers);
+		ManifestParser parser = new ManifestParser(log, config, this, headers);
+		m_symbolicName = parser.getSymbolicName();
+		m_version = parser.getBundleVersion();
+		m_declaredCaps = (m_bundle.getBundleId() != 0) ? parser.getCapabilities() : aliasSymbolicName(parser.getCapabilities());
+		m_declaredReqs = parser.getRequirements();
+		m_type = headers.containsKey(Constants.FRAGMENT_HOST) ? BundleRevision.TYPE_FRAGMENT : 0;
+		m_declaredLibs = parser.getLibraries();
+	}
+
+    /**
+     * Takes a given list of bundle capabilities and patches all symbolic names to be marked as system bundles.
+     * 
+     * @param capabilities the capabilities to patch, may be <code>null</code>.
+     * @return the patched capabilities, or an emtpy list in case the given capabilities was <code>null</code>.
+     */
+    private static List<BundleCapability> aliasSymbolicName(List<BundleCapability> capabilities)
+    {
+        if (capabilities == null)
+        {
+            return Collections.emptyList();
+        }
+
+        List<BundleCapability> aliasCaps = new ArrayList<BundleCapability>(capabilities);
+
+        for (int capIdx = 0; capIdx < aliasCaps.size(); capIdx++)
+        {
+            BundleCapability capability = aliasCaps.get(capIdx);
+            
+            // Get the attributes and search for bundle symbolic name.
+            Map<String, Object> attributes = capability.getAttributes();
+            
+            for (Entry<String, Object> entry : attributes.entrySet())
+            {
+                // If there is a bundle symbolic name attribute, add the
+                // standard alias as a value.
+                if (Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE.equalsIgnoreCase(entry.getKey()))
+                {
+                    // Make a copy of the attribute array.
+                    Map<String, Object> aliasAttrs = new HashMap<String, Object>(attributes);
+                    // Add the aliased value.
+                    aliasAttrs.put(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, new String[] { (String) entry.getValue(), Constants.SYSTEM_BUNDLE_SYMBOLICNAME });
+                    // Create the aliased capability to replace the old capability.
+                    aliasCaps.set(capIdx, new BundleCapabilityImpl(capability.getRevision(), capability.getNamespace(), capability.getDirectives(), aliasAttrs));
+                    // Continue with the next capability.
+                    break;
+                }
+            }
+        }
+
+        return aliasCaps;
+    }
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Bundle getBundle() {
+		return m_bundle;
+	}
+
+    /**
+     * {@inheritDoc}
+     */
+	public String getSymbolicName() {
+		return m_symbolicName;
+	}
+
+    /**
+     * {@inheritDoc}
+     */
+	public Version getVersion() {
+		return m_version;
+	}
+
+    /**
+     * {@inheritDoc}
+     */
+	public List<BundleCapability> getDeclaredCapabilities(String namespace) {
+		return m_declaredCaps;
+	}
+
+    /**
+     * {@inheritDoc}
+     */
+	public List<BundleRequirement> getDeclaredRequirements(String namespace) {
+		return m_declaredReqs;
+	}
+	
+    /**
+     * {@inheritDoc}
+     */
+	public List<R4Library> getDeclaredNativeLibraries() {
+		return m_declaredLibs;
+	}
+
+    /**
+     * {@inheritDoc}
+     */
+	public int getTypes() {
+		return m_type;
+	}
+
+    /**
+     * {@inheritDoc}
+     */
+	public BundleWiring getWiring() {
+		return null;
+	}
+
+    /**
+     * {@inheritDoc}
+     */
+	public Map<String, String> getHeaders() {
+		return m_headers;
+	}
+	
+	/**
+	 * Returns the required execution environment, if defined.
+	 * 
+	 * @return the required execution environment, can be <code>null</code> if not defined.
+	 */
+	@SuppressWarnings("deprecation")
+    public String getRequiredExecutionEnvironment() {
+	    String result = getHeaders().get(Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT);
+        return result == null ? null : result.trim();
+	}
+	
+    /**
+     * {@inheritDoc}
+     */
+	public int hashCode() {
+		return (int) getBundle().getBundleId();
+	}
+	
+    /**
+     * {@inheritDoc}
+     */
+	public boolean equals(Object o) {
+		if (o instanceof VerifierBundleRevision) {
+			return o.hashCode() == hashCode();
+		}
+		return false;
+	}
+	
+    /**
+     * {@inheritDoc}
+     */
+	public String toString() {
+		return m_symbolicName + ";"+ Constants.VERSION_ATTRIBUTE + "=" + m_version + "(id=" + getBundle().getBundleId() + ")";
+	}
+}

Added: ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/impl/VerifierResolverState.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/impl/VerifierResolverState.java?rev=1464402&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/impl/VerifierResolverState.java (added)
+++ ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/impl/VerifierResolverState.java Thu Apr  4 09:43:34 2013
@@ -0,0 +1,342 @@
+/*
+ * 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.ace.deployment.verifier.impl;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.StringTokenizer;
+import java.util.TreeSet;
+
+import org.apache.felix.framework.capabilityset.CapabilitySet;
+import org.apache.felix.framework.capabilityset.SimpleFilter;
+import org.apache.felix.framework.resolver.CandidateComparator;
+import org.apache.felix.framework.resolver.ResolveException;
+import org.apache.felix.framework.resolver.Resolver;
+import org.apache.felix.framework.resolver.Resolver.ResolverState;
+import org.apache.felix.framework.util.Util;
+import org.apache.felix.framework.util.manifestparser.R4Library;
+import org.apache.felix.framework.wiring.BundleRequirementImpl;
+import org.osgi.framework.Constants;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleRevision;
+
+/**
+ * Provides a custom {@link ResolverState} implementation to hold all state during resolving.
+ */
+public class VerifierResolverState implements Resolver.ResolverState {
+
+	// Set of all revisions.
+	private final Set<BundleRevision> m_revisions;
+	// Set of all fragments.
+	private final Set<BundleRevision> m_fragments;
+	// Capability sets.
+	private final Map<String, CapabilitySet> m_capSets;
+	// Execution environment.
+	private final String m_fwkExecEnvStr;
+	// Parsed framework environments
+	private final Set<String> m_fwkExecEnvSet;
+
+	/**
+	 * Creates a new {@link VerifierResolverState} instance.
+	 * 
+	 * @param fwkExecEnvStr the framework execution environment, can be <code>null</code>.
+	 */
+	public VerifierResolverState(String fwkExecEnvStr) {
+		m_revisions = new HashSet<BundleRevision>();
+		m_fragments = new HashSet<BundleRevision>();
+		m_capSets = new HashMap<String, CapabilitySet>();
+
+		m_fwkExecEnvStr = (fwkExecEnvStr != null) ? fwkExecEnvStr.trim() : null;
+		m_fwkExecEnvSet = parseExecutionEnvironments(fwkExecEnvStr);
+
+		List<String> indices = new ArrayList<String>();
+		indices.add(BundleRevision.BUNDLE_NAMESPACE);
+		m_capSets.put(BundleRevision.BUNDLE_NAMESPACE, new CapabilitySet(indices, true));
+
+		indices = new ArrayList<String>();
+		indices.add(BundleRevision.PACKAGE_NAMESPACE);
+		m_capSets.put(BundleRevision.PACKAGE_NAMESPACE, new CapabilitySet(indices, true));
+
+		indices = new ArrayList<String>();
+		indices.add(BundleRevision.HOST_NAMESPACE);
+		m_capSets.put(BundleRevision.HOST_NAMESPACE, new CapabilitySet(indices, true));
+	}
+
+	synchronized Set<BundleRevision> getUnresolvedRevisions() {
+		Set<BundleRevision> unresolved = new HashSet<BundleRevision>();
+		for (BundleRevision revision : m_revisions) {
+			if (revision.getWiring() == null) {
+				unresolved.add(revision);
+			}
+		}
+		return unresolved;
+	}
+
+	synchronized void addRevision(BundleRevision br) {
+		// Always attempt to remove the revision, since
+		// this method can be used for re-indexing a revision
+		// after it has been resolved.
+		removeRevision(br);
+
+		// Add the revision and index its declared or resolved
+		// capabilities depending on whether it is resolved or
+		// not.
+		m_revisions.add(br);
+		List<BundleCapability> caps = (br.getWiring() == null) ? br
+				.getDeclaredCapabilities(null) : br.getWiring()
+				.getCapabilities(null);
+		if (caps != null) {
+			for (BundleCapability cap : caps) {
+				// If the capability is from a different revision, then
+				// don't index it since it is a capability from a fragment.
+				// In that case, the fragment capability is still indexed.
+				if (cap.getRevision() == br) {
+					CapabilitySet capSet = m_capSets.get(cap.getNamespace());
+					if (capSet == null) {
+						capSet = new CapabilitySet(null, true);
+						m_capSets.put(cap.getNamespace(), capSet);
+					}
+					capSet.addCapability(cap);
+				}
+			}
+		}
+
+		if (Util.isFragment(br)) {
+			m_fragments.add(br);
+		}
+	}
+
+	synchronized void removeRevision(BundleRevision br) {
+		if (m_revisions.remove(br)) {
+			// We only need be concerned with declared capabilities here,
+			// because resolved capabilities will be a subset.
+			List<BundleCapability> caps = br.getDeclaredCapabilities(null);
+			if (caps != null) {
+				for (BundleCapability cap : caps) {
+					CapabilitySet capSet = m_capSets.get(cap.getNamespace());
+					if (capSet != null) {
+						capSet.removeCapability(cap);
+					}
+				}
+			}
+
+			if (Util.isFragment(br)) {
+				m_fragments.remove(br);
+			}
+		}
+	}
+
+	synchronized Set<BundleRevision> getFragments() {
+		return new HashSet(m_fragments);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean isEffective(BundleRequirement req) {
+		String effective = req.getDirectives().get(Constants.EFFECTIVE_DIRECTIVE);
+		return ((effective == null) || effective.equals(Constants.EFFECTIVE_RESOLVE));
+	}
+
+    /**
+     * {@inheritDoc}
+     */
+	public synchronized SortedSet<BundleCapability> getCandidates(BundleRequirement req, boolean obeyMandatory) {
+//		BundleRevision reqRevision = req.getRevision();
+		SortedSet<BundleCapability> result = new TreeSet<BundleCapability>(new CandidateComparator());
+
+		CapabilitySet capSet = m_capSets.get(req.getNamespace());
+		if (capSet != null) {
+			// Get the requirement's filter; if this is our own impl we
+			// have a shortcut to get the already parsed filter, otherwise
+			// we must parse it from the directive.
+			SimpleFilter sf = null;
+			if (req instanceof BundleRequirementImpl) {
+				sf = ((BundleRequirementImpl) req).getFilter();
+			} else {
+				String filter = req.getDirectives().get(
+						Constants.FILTER_DIRECTIVE);
+				if (filter == null) {
+					sf = new SimpleFilter(null, null, SimpleFilter.MATCH_ALL);
+				} else {
+					sf = SimpleFilter.parse(filter);
+				}
+			}
+
+			// Find the matching candidates.
+			Set<BundleCapability> matches = capSet.match(sf, obeyMandatory);
+			for (BundleCapability cap : matches) {
+				/* TODO: karl - is this correct?
+				 * if (System.getSecurityManager() != null) {
+					if (req.getNamespace().equals(
+							BundleRevision.PACKAGE_NAMESPACE)
+							&& (!((BundleProtectionDomain) ((BundleRevisionImpl) cap
+									.getRevision()).getProtectionDomain())
+									.impliesDirect(new PackagePermission(
+											(String) cap
+													.getAttributes()
+													.get(BundleRevision.PACKAGE_NAMESPACE),
+											PackagePermission.EXPORTONLY)) || !((reqRevision == null) || ((BundleProtectionDomain) reqRevision
+									.getProtectionDomain())
+									.impliesDirect(new PackagePermission(
+											(String) cap
+													.getAttributes()
+													.get(BundleRevision.PACKAGE_NAMESPACE),
+											cap.getRevision().getBundle(),
+											PackagePermission.IMPORT))))) {
+						if (reqRevision != cap.getRevision()) {
+							continue;
+						}
+					} else if (req.getNamespace().equals(
+							BundleRevision.BUNDLE_NAMESPACE)
+							&& (!((BundleProtectionDomain) ((BundleRevisionImpl) cap
+									.getRevision()).getProtectionDomain())
+									.impliesDirect(new BundlePermission(cap
+											.getRevision().getSymbolicName(),
+											BundlePermission.PROVIDE)) || !((reqRevision == null) || ((BundleProtectionDomain) reqRevision
+									.getProtectionDomain())
+									.impliesDirect(new BundlePermission(
+											reqRevision.getSymbolicName(),
+											BundlePermission.REQUIRE))))) {
+						continue;
+					} else if (req.getNamespace().equals(
+							BundleRevision.HOST_NAMESPACE)
+							&& (!((BundleProtectionDomain) reqRevision
+									.getProtectionDomain())
+									.impliesDirect(new BundlePermission(
+											reqRevision.getSymbolicName(),
+											BundlePermission.FRAGMENT)) || !((BundleProtectionDomain) ((BundleRevisionImpl) cap
+									.getRevision()).getProtectionDomain())
+									.impliesDirect(new BundlePermission(cap
+											.getRevision().getSymbolicName(),
+											BundlePermission.HOST)))) {
+						continue;
+					}
+				}*/
+
+				if (req.getNamespace().equals(BundleRevision.HOST_NAMESPACE)
+						&& (cap.getRevision().getWiring() != null)) {
+					continue;
+				}
+
+				result.add(cap);
+			}
+		}
+
+		// If we have resolver hooks, then we may need to filter our results
+		// based on a whitelist and/or fine-grained candidate filtering.
+		/*TODO: karl - is this correct?
+		 * if (!result.isEmpty() && !m_hooks.isEmpty()) {
+		 
+			// It we have a whitelist, then first filter out candidates
+			// from disallowed revisions.
+			if (m_whitelist != null) {
+				for (Iterator<BundleCapability> it = result.iterator(); it
+						.hasNext();) {
+					if (!m_whitelist.contains(it.next().getRevision())) {
+						it.remove();
+					}
+				}
+			}
+
+			// Now give the hooks a chance to do fine-grained filtering.
+			ShrinkableCollection<BundleCapability> shrinkable = new ShrinkableCollection<BundleCapability>(
+					result);
+			for (ResolverHook hook : m_hooks) {
+				try {
+					Felix.m_secureAction.invokeResolverHookMatches(hook, req,
+							shrinkable);
+				} catch (Throwable th) {
+					m_logger.log(Logger.LOG_WARNING,
+							"Resolver hook exception.", th);
+				}
+			}
+		}*/
+
+		return result;
+	}
+
+    /**
+     * {@inheritDoc}
+     */
+	public void checkExecutionEnvironment(BundleRevision revision) throws ResolveException {
+		String bundleExecEnvStr = ((VerifierBundleRevision) revision).getRequiredExecutionEnvironment();
+		if (bundleExecEnvStr != null) {
+			// If the bundle has specified an execution environment and the
+			// framework has an execution environment specified, then we must
+			// check for a match.
+			if (!bundleExecEnvStr.equals("") && (m_fwkExecEnvStr != null) && (m_fwkExecEnvStr.length() > 0)) {
+				StringTokenizer tokens = new StringTokenizer(bundleExecEnvStr, ",");
+
+				boolean found = false;
+				while (tokens.hasMoreTokens() && !found) {
+					if (m_fwkExecEnvSet.contains(tokens.nextToken().trim())) {
+						found = true;
+					}
+				}
+				
+				if (!found) {
+					throw new ResolveException("Execution environment not supported: " + bundleExecEnvStr, revision, null);
+				}
+			}
+		}
+	}
+
+    /**
+     * {@inheritDoc}
+     */
+	public void checkNativeLibraries(BundleRevision revision) throws ResolveException {
+		// Next, try to resolve any native code, since the revision is
+		// not resolvable if its native code cannot be loaded.
+		List<R4Library> libs = ((VerifierBundleRevision) revision).getDeclaredNativeLibraries();
+		// If we have a zero-length native library array, then
+		// this means no native library class could be selected
+		// so we should fail to resolve.
+		if ((libs != null) && libs.isEmpty()) {
+			throw new ResolveException("No matching native libraries found.", revision, null);
+		}
+	}
+
+	/**
+	 * Updates the framework wide execution environment string and a cached Set
+	 * of execution environment tokens from the comma delimited list specified
+	 * by the system variable 'org.osgi.framework.executionenvironment'.
+	 * 
+	 * @param fwkExecEnvStr
+	 *            Comma delimited string of provided execution environments
+	 * @return the parsed set of execution environments
+	 **/
+	private static Set<String> parseExecutionEnvironments(String fwkExecEnvStr) {
+		Set<String> newSet = new HashSet<String>();
+		if (fwkExecEnvStr != null) {
+			StringTokenizer tokens = new StringTokenizer(fwkExecEnvStr, ",");
+			while (tokens.hasMoreTokens()) {
+				newSet.add(tokens.nextToken().trim());
+			}
+		}
+		return newSet;
+	}
+
+}

Added: ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/impl/VerifierServiceImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/impl/VerifierServiceImpl.java?rev=1464402&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/impl/VerifierServiceImpl.java (added)
+++ ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/impl/VerifierServiceImpl.java Thu Apr  4 09:43:34 2013
@@ -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.ace.deployment.verifier.impl;
+
+import java.util.Map;
+
+import org.apache.ace.deployment.verifier.VerifierService;
+
+/**
+ * Provides a verifier service implementation.
+ */
+public class VerifierServiceImpl implements VerifierService {
+    
+    /**
+     * {@inheritDoc}
+     */
+	public VerifyEnvironment createEnvironment(Map<String, String> config, VerifyReporter reporter) {
+		return new VerifyEnvironmentImpl(config, reporter);
+	}
+}

Added: ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/impl/VerifyEnvironmentImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/impl/VerifyEnvironmentImpl.java?rev=1464402&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/impl/VerifyEnvironmentImpl.java (added)
+++ ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/impl/VerifyEnvironmentImpl.java Thu Apr  4 09:43:34 2013
@@ -0,0 +1,336 @@
+/*
+ * 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.ace.deployment.verifier.impl;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.security.cert.X509Certificate;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.ace.deployment.verifier.VerifierService;
+import org.apache.ace.deployment.verifier.VerifierService.VerifyEnvironment;
+import org.apache.ace.deployment.verifier.VerifierService.VerifyReporter;
+import org.apache.felix.framework.Logger;
+import org.apache.felix.framework.resolver.Resolver;
+import org.apache.felix.framework.resolver.ResolverImpl;
+import org.apache.felix.framework.resolver.ResolverWire;
+import org.apache.felix.framework.util.MapToDictionary;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.service.log.LogEntry;
+
+/**
+ * Provides a {@link VerifyEnvironment} implementation.
+ */
+public class VerifyEnvironmentImpl implements VerifierService.VerifyEnvironment {
+
+    /**
+     * Provides a dummy bundle implementation.
+     */
+    private static final class DummyBundle implements Bundle {
+        private final Map<String, String> m_manifest;
+        private final long m_id;
+
+        /**
+         * @param id
+         * @param manifest
+         */
+        private DummyBundle(long id, Map<String, String> manifest) {
+            m_id = id;
+            m_manifest = manifest;
+        }
+
+        public <A> A adapt(Class<A> type) {
+            return null;
+        }
+
+        public int compareTo(Bundle o) {
+            return (int) (o.getBundleId() - getBundleId());
+        }
+
+        public Enumeration<URL> findEntries(String path, String filePattern, boolean recurse) {
+            return null;
+        }
+
+        public BundleContext getBundleContext() {
+            return null;
+        }
+
+        public long getBundleId() {
+            return m_id;
+        }
+
+        public File getDataFile(String filename) {
+            return null;
+        }
+
+        public URL getEntry(String path) {
+            return null;
+        }
+
+        public Enumeration<String> getEntryPaths(String path) {
+            return null;
+        }
+
+        public Dictionary<String, String> getHeaders() {
+            return new MapToDictionary(m_manifest);
+        }
+
+        public Dictionary<String, String> getHeaders(String locale) {
+            return getHeaders();
+        }
+
+        public long getLastModified() {
+            return 0;
+        }
+
+        public String getLocation() {
+            return null;
+        }
+
+        public ServiceReference<?>[] getRegisteredServices() {
+            return null;
+        }
+
+        public URL getResource(String name) {
+            return null;
+        }
+
+        public Enumeration<URL> getResources(String name) throws IOException {
+            return null;
+        }
+
+        public ServiceReference<?>[] getServicesInUse() {
+            return null;
+        }
+
+        public Map<X509Certificate, List<X509Certificate>> getSignerCertificates(int signersType) {
+            return null;
+        }
+
+        public int getState() {
+            return Bundle.INSTALLED;
+        }
+
+        public String getSymbolicName() {
+            return null;
+        }
+
+        public Version getVersion() {
+            return null;
+        }
+
+        public boolean hasPermission(Object permission) {
+            return false;
+        }
+
+        public Class<?> loadClass(String name) throws ClassNotFoundException {
+            return null;
+        }
+
+        public void start() throws BundleException {
+            // Nop
+        }
+
+        public void start(int options) throws BundleException {
+            // Nop
+        }
+
+        public void stop() throws BundleException {
+            // Nop
+        }
+
+        public void stop(int options) throws BundleException {
+            // Nop
+        }
+
+        public void uninstall() throws BundleException {
+            // Nop
+        }
+
+        public void update() throws BundleException {
+            // Nop
+        }
+
+        public void update(InputStream input) throws BundleException {
+            // Nop
+        }
+    }
+
+    /**
+     * Provides a dummy {@link VerifyReporter} implementation that does nothing.
+     */
+    private static final class DummyReporter implements VerifyReporter {
+        public void reportException(Exception ex) {
+            // Nop
+        }
+
+        public void reportLog(LogEntry entry) {
+            // Nop
+        }
+
+        public void reportWire(BundleRevision importer, BundleRequirement reqirement, BundleRevision exporter,
+            BundleCapability capability) {
+            // Nop
+        }
+    }
+
+    /**
+     * Provides a logger implementation for intercepting all framework logging calls.
+     */
+    private static final class FrameworkLogger {
+        private final VerifyReporter m_reporter;
+        
+        /**
+         * Creates a new {@link FrameworkLogger} instance.
+         * 
+         * @param reporter the {@link VerifyReporter} to route all logging to, cannot be <code>null</code>.
+         */
+        public FrameworkLogger(VerifyReporter reporter) {
+            m_reporter = reporter;
+        }
+        
+        @SuppressWarnings("unused")
+        public void log(final ServiceReference ref, final int level, final String message, final Throwable t) {
+            final long time = System.currentTimeMillis();
+
+            m_reporter.reportLog(new LogEntry() {
+                public Bundle getBundle() {
+                    return null;
+                }
+
+                public Throwable getException() {
+                    return t;
+                }
+
+                public int getLevel() {
+                    return level;
+                }
+
+                public String getMessage() {
+                    return message;
+                }
+
+                public ServiceReference getServiceReference() {
+                    return ref;
+                }
+
+                public long getTime() {
+                    return time;
+                }
+            });
+        }
+    }
+
+    private final Logger m_log;
+    private final VerifyReporter m_reporter;
+    private final Map<String, String> m_config;
+    private final ConcurrentMap<Long, VerifierBundleRevision> m_bundles;
+
+    /**
+     * Creates a new {@link VerifyEnvironmentImpl} instance.
+     * 
+     * @param config the configuration to use, cannot be <code>null</code>;
+     * @param reporter the {@link VerifyReporter} to use, can be <code>null</code> in which case a dummy reporter will be used.
+     */
+    public VerifyEnvironmentImpl(Map<String, String> config, VerifyReporter reporter) {
+
+        m_config = config;
+        m_reporter = (reporter == null) ? new DummyReporter() : reporter;
+        m_bundles = new ConcurrentHashMap<Long, VerifierBundleRevision>();
+        
+        m_log = new Logger();
+        m_log.setLogger(new FrameworkLogger(m_reporter));
+        m_log.setLogLevel(Logger.LOG_DEBUG);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public BundleRevision addBundle(final long id, final Map<String, String> manifest) throws BundleException {
+        VerifierBundleRevision rev = new VerifierBundleRevision(m_log, new DummyBundle(id, manifest), m_config, manifest);
+
+        if (m_bundles.putIfAbsent(id, rev) != null) {
+            throw new BundleException("Bundle already exists for id: " + id);
+        }
+
+        return rev;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean verifyResolve(Set<BundleRevision> mandatory, Set<BundleRevision> optional, Set<BundleRevision> ondemandFragments) {
+
+        VerifierResolverState state = new VerifierResolverState(getFrameworkExecutionEnvironment());
+
+        for (VerifierBundleRevision rev : m_bundles.values()) {
+            state.addRevision(rev);
+        }
+
+        Resolver resolver = new ResolverImpl(m_log);
+
+        try {
+            Map<BundleRevision, List<ResolverWire>> result = resolver.resolve(
+                state,
+                (mandatory == null) ? new HashSet<BundleRevision>() : mandatory,
+                (optional == null) ? new HashSet<BundleRevision>() : optional,
+                (ondemandFragments == null) ? new HashSet<BundleRevision>() : ondemandFragments);
+
+            for (Entry<BundleRevision, List<ResolverWire>> entry : result.entrySet()) {
+                for (ResolverWire wire : entry.getValue()) {
+                    m_reporter.reportWire(wire.getRequirer(), wire.getRequirement(), wire.getProvider(), wire.getCapability());
+                }
+            }
+        }
+        catch (Exception ex) {
+            m_reporter.reportException(ex);
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * @return the framework execution environment, can be <code>null</code>.
+     */
+    @SuppressWarnings("deprecation")
+    private String getFrameworkExecutionEnvironment() {
+        return this.m_config.get(Constants.FRAMEWORK_EXECUTIONENVIRONMENT);
+    }
+
+}
\ No newline at end of file

Added: ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/packageinfo
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/packageinfo?rev=1464402&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/packageinfo (added)
+++ ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/packageinfo Thu Apr  4 09:43:34 2013
@@ -0,0 +1 @@
+version 1.0
\ No newline at end of file

Added: ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/ui/ACEVerifierExtension.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/ui/ACEVerifierExtension.java?rev=1464402&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/ui/ACEVerifierExtension.java (added)
+++ ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/ui/ACEVerifierExtension.java Thu Apr  4 09:43:34 2013
@@ -0,0 +1,412 @@
+/*
+ * 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.ace.deployment.verifier.ui;
+
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.jar.Attributes;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+
+import org.apache.ace.client.repository.RepositoryObject;
+import org.apache.ace.client.repository.object.DeploymentArtifact;
+import org.apache.ace.client.repository.object.DeploymentVersionObject;
+import org.apache.ace.client.repository.repository.DeploymentVersionRepository;
+import org.apache.ace.client.repository.stateful.StatefulTargetObject;
+import org.apache.ace.deployment.verifier.VerifierService;
+import org.apache.ace.deployment.verifier.VerifierService.VerifyEnvironment;
+import org.apache.ace.deployment.verifier.VerifierService.VerifyReporter;
+import org.apache.ace.connectionfactory.ConnectionFactory;
+import org.apache.ace.webui.NamedObject;
+import org.apache.ace.webui.UIExtensionFactory;
+import org.osgi.framework.Constants;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.service.log.LogEntry;
+
+import com.vaadin.data.Property;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Panel;
+import com.vaadin.ui.PopupView;
+import com.vaadin.ui.TextArea;
+import com.vaadin.ui.VerticalLayout;
+
+public class ACEVerifierExtension implements UIExtensionFactory {
+
+    /**
+     *
+     */
+    final class ManifestArea extends VerticalLayout implements Property.ValueChangeListener, Button.ClickListener {
+        private final String m_id;
+        private final TextArea m_editor;
+        private final Label m_plainText;
+        private final StatefulTargetObject m_object;
+        private final PopupView m_popup;
+
+        public ManifestArea(String id, String initialText, StatefulTargetObject object) {
+            setWidth("100%");
+
+            m_id = id;
+            m_object = object;
+
+            m_editor = new TextArea(null, initialText);
+            m_editor.setRows(15);
+            m_editor.addListener(this);
+            m_editor.setImmediate(true);
+            m_editor.setWidth("100%");
+            m_editor.setHeight("70%");
+
+            m_plainText = new Label();
+            m_plainText.setContentMode(Label.CONTENT_XHTML);
+            m_plainText.setImmediate(true);
+            m_plainText.setSizeFull();
+
+            Panel panel = new Panel();
+            panel.setCaption("Verification result");
+            panel.getContent().addComponent(m_plainText);
+            panel.setWidth("800px");
+            panel.setHeight("300px");
+
+            m_popup = new PopupView("Result", panel);
+            m_popup.setCaption("Verification result");
+            m_popup.setHideOnMouseOut(false);
+            m_popup.setVisible(false);
+
+            Button verify = new Button("Verify", this);
+
+            addComponent(m_editor);
+            addComponent(verify);
+            addComponent(m_popup);
+        }
+
+        public void buttonClick(ClickEvent event) {
+            if (m_popup.isPopupVisible()) {
+                m_popup.setPopupVisible(false);
+            }
+
+            String output;
+            try {
+                String manifest = m_editor.getValue().toString();
+                output = verify(m_id, manifest);
+            }
+            catch (Exception e) {
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                e.printStackTrace(new PrintStream(baos));
+                output = baos.toString();
+            }
+
+            m_plainText.setValue(output);
+
+            m_popup.setVisible(true);
+            m_popup.setPopupVisible(true);
+        }
+
+        public void valueChange(ValueChangeEvent event) {
+            String text = (String) m_editor.getValue();
+
+            if (text != null) {
+                m_object.addAttribute("manifest", text);
+            }
+        }
+    }
+
+    // Injected by Dependency Manager
+    private volatile VerifierService m_verifier;
+    private volatile DeploymentVersionRepository m_repo;
+    private volatile ConnectionFactory m_connectionFactory;
+
+    /**
+     * {@inheritDoc}
+     */
+    public Component create(Map<String, Object> context) {
+        RepositoryObject object = getRepositoryObjectFromContext(context);
+
+        Component content = new Label("This target is not yet registered, so it can not verify anything.");
+        if (object instanceof StatefulTargetObject) {
+            StatefulTargetObject statefulTarget = (StatefulTargetObject) object;
+            if (statefulTarget.isRegistered()) {
+                content = new ManifestArea(statefulTarget.getID(), getManifest(statefulTarget), statefulTarget);
+            }
+        }
+
+        VerticalLayout result = new VerticalLayout();
+        result.setMargin(true);
+        result.setCaption("Verify/resolve");
+        result.addComponent(content);
+
+        return result;
+    }
+
+    /**
+     * Performs the actual verification.
+     */
+    final String verify(String targetId, String manifestText) throws Exception {
+        DeploymentVersionObject version = m_repo.getMostRecentDeploymentVersion(targetId);
+        if (version == null) {
+            return "No deployment version available to verify.";
+        }
+
+        VerificationResult result = new VerificationResult();
+        Map<String, String> manifestMap = getManifestEntries(manifestText);
+
+        VerifyEnvironment env = createVerifyEnvironment(manifestMap, result);
+
+        // Add the main entry...
+        result.addBundle(env, manifestMap);
+
+        processArtifacts(version.getDeploymentArtifacts(), env, result);
+
+        StringBuilder sb = new StringBuilder();
+        if (result.hasCustomizers()) {
+            if (!result.allCustomizerMatch()) {
+                sb.append("<p><b>Not all bundle customizers match!</b><br/>");
+                sb.append("Provided = ").append(result.getCustomizers().toString()).append("<br/>");
+                sb.append("Required = ").append(result.getProcessors().toString()).append(".</p>");
+            }
+            else {
+                sb.append("<p>All bundle customizers match!</p>");
+            }
+        }
+
+        boolean resolves = env.verifyResolve(result.getBundles(), null, null);
+        if (resolves) {
+            sb.append("<p>Deployment package resolves.<br/>");
+        }
+        else {
+            sb.append("<p>Deployment package does <b>not</b> resolve!<br/>");
+        }
+
+        sb.append("Details:<br/>");
+        sb.append(result.toString()).append("</p>");
+
+        return sb.toString();
+    }
+
+    /**
+     * Quietly closes a given {@link Closeable}.
+     * 
+     * @param closeable the closeable to close, can be <code>null</code>.
+     */
+    private void closeQuietly(Closeable closeable) {
+        if (closeable != null) {
+            try {
+                closeable.close();
+            }
+            catch (IOException ex) {
+                // Ignore quietly...
+            }
+        }
+    }
+
+    /**
+     * Factory method to create a suitable {@link VerifyEnvironment} instance.
+     * 
+     * @param manifest the manifest to use;
+     * @param verifyResult the verification result to use.
+     * @return a new {@link VerifyEnvironment} instance, never <code>null</code>.
+     */
+    @SuppressWarnings("deprecation")
+    private VerifyEnvironment createVerifyEnvironment(Map<String, String> manifest, final VerificationResult verifyResult) {
+        String ee = manifest.get(Constants.FRAMEWORK_EXECUTIONENVIRONMENT);
+        if (ee == null) {
+            ee = VerifierService.EE_1_6;
+        }
+
+        Map<String, String> envMap = Collections.singletonMap(Constants.FRAMEWORK_EXECUTIONENVIRONMENT, ee);
+
+        VerifyEnvironment env = m_verifier.createEnvironment(envMap, new VerifyReporter() {
+            public void reportException(Exception ex) {
+                ex.printStackTrace(verifyResult.m_out);
+            }
+
+            public void reportLog(LogEntry logEntry) {
+                verifyResult.m_out.printf("Log (%l): [%s] %s", logEntry.getTime(), logEntry.getLevel(), logEntry.getMessage());
+
+                Throwable ex = logEntry.getException();
+                if (ex != null) {
+                    ex.printStackTrace(verifyResult.m_out);
+                }
+            }
+
+            public void reportWire(BundleRevision importer, BundleRequirement requirement, BundleRevision exporter,
+                BundleCapability capability) {
+                verifyResult.m_out.println("<tt>WIRE: " + requirement + " -> " + capability + "</tt><br/>");
+            }
+        });
+        return env;
+    }
+
+    /**
+     * Returns a "static"/hardcoded manifest.
+     * 
+     * @return a manifest, never <code>null</code>.
+     */
+    private String defineStaticManifest() {
+        // @formatter:off
+        return Constants.BUNDLE_MANIFESTVERSION + ": 2\n" + 
+               Constants.BUNDLE_SYMBOLICNAME + ": org.apache.felix.framework\n" + 
+               Constants.EXPORT_PACKAGE + ": " + VerifierService.SYSTEM_PACKAGES + "," + VerifierService.JRE_1_6_PACKAGES + "," + 
+               "org.osgi.service.cm; version=1.2," +
+               "org.osgi.service.metatype; version=1.1.1," + 
+               "org.osgi.service.cm; version=1.3.0," + 
+               "org.osgi.service.deploymentadmin.spi; version=1.0.1," +
+               "org.osgi.service.deploymentadmin; version=1.1.0\n";
+        // @formatter:on
+    }
+
+    /**
+     * Returns the manifest for a given repository object.
+     * <p>In case the given repository object does not provide a manifest, this method will return a hard-coded manifest.</p>
+     * 
+     * @param object the repository object to get the manifest for, cannot be <code>null</code>.
+     * @return a manifest, never <code>null</code>.
+     */
+    private String getManifest(RepositoryObject object) {
+        String manifest = object.getAttribute("manifest");
+        if (manifest == null) {
+            manifest = defineStaticManifest();
+        }
+        return manifest;
+    }
+
+    /**
+     * Converts a given {@link Attributes} into a map.
+     * 
+     * @param attributes the attributes to convert, cannot be <code>null</code>.
+     * @return a manifest map, never <code>null</code>.
+     */
+    private Map<String, String> getManifestEntries(final Manifest manifest) {
+        Attributes attributes = manifest.getMainAttributes();
+
+        Map<String, String> entries = new HashMap<String, String>();
+        for (Map.Entry<Object, Object> entry : attributes.entrySet()) {
+            entries.put(entry.getKey().toString(), entry.getValue().toString());
+        }
+        return entries;
+    }
+
+    /**
+     * @param manifestText
+     * @return
+     */
+    private Map<String, String> getManifestEntries(String manifestText) {
+        StringTokenizer tok = new StringTokenizer(manifestText, ":\n");
+
+        Map<String, String> manMap = new HashMap<String, String>();
+        while (tok.hasMoreTokens()) {
+            manMap.put(tok.nextToken(), tok.nextToken());
+        }
+        return manMap;
+    }
+
+    /**
+     * @param context
+     * @return
+     */
+    private RepositoryObject getRepositoryObjectFromContext(Map<String, Object> context) {
+        Object contextObject = context.get("object");
+        if (contextObject == null) {
+            throw new IllegalStateException("No context object found");
+        }
+
+        return ((RepositoryObject) (contextObject instanceof NamedObject ? ((NamedObject) contextObject).getObject()
+            : contextObject));
+    }
+
+    /**
+     * Processes all artifacts.
+     * 
+     * @param artifacts the artifacts to process.
+     * @param env the environment to use;
+     * @param verifyResult the verification result, cannot be <code>null</code>.
+     */
+    private void processArtifacts(DeploymentArtifact[] artifacts, VerifyEnvironment env, VerificationResult verifyResult) {
+        String dir;
+        for (DeploymentArtifact artifact : artifacts) {
+            if (artifact.getDirective(Constants.BUNDLE_SYMBOLICNAME) != null) {
+                processBundle(artifact, env, verifyResult);
+            }
+            else if ((dir = artifact.getDirective("Resource-Processor")) != null) {
+                verifyResult.addProcessor(dir);
+            }
+        }
+    }
+
+    /**
+     * Processes a single bundle.
+     * 
+     * @param bundle the bundle to process;
+     * @param env the environment to use;
+     * @param verifyResult the verification result, cannot be <code>null</code>.
+     */
+    private void processBundle(DeploymentArtifact bundle, VerifyEnvironment env, VerificationResult verifyResult) {
+        InputStream is = null;
+        JarInputStream jis = null;
+
+        try {
+            is = getBundleContents(bundle.getUrl());
+            jis = new JarInputStream(is, false /* verify */);
+
+            Map<String, String> manifest = getManifestEntries(jis.getManifest());
+
+            verifyResult.addBundle(env, manifest);
+
+            if (manifest.get("DeploymentPackage-Customizer") != null) {
+                String typeString = manifest.get("Deployment-ProvidesResourceProcessor");
+                if (typeString != null) {
+                    String[] types = typeString.split(",");
+                    for (String type : types) {
+                        verifyResult.addCustomizer(type);
+                    }
+                }
+            }
+        }
+        catch (Exception ex) {
+            ex.printStackTrace(verifyResult.m_out);
+        }
+        finally {
+            closeQuietly(is);
+            closeQuietly(jis);
+        }
+    }
+
+    /**
+     * @param url the remote URL to connect to, cannot be <code>null</code>.
+     * @return an {@link InputStream} to the remote URL, never <code>null</code>.
+     * @throws IOException in case of I/O problems opening the remote connection.
+     */
+    private InputStream getBundleContents(String url) throws IOException {
+        URLConnection conn = m_connectionFactory.createConnection(new URL(url));
+        return conn.getInputStream();
+    }
+}

Added: ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/ui/Activator.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/ui/Activator.java?rev=1464402&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/ui/Activator.java (added)
+++ ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/ui/Activator.java Thu Apr  4 09:43:34 2013
@@ -0,0 +1,61 @@
+/*
+ * 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.ace.deployment.verifier.ui;
+
+import java.util.Properties;
+
+import org.apache.ace.client.repository.repository.DeploymentVersionRepository;
+import org.apache.ace.connectionfactory.ConnectionFactory;
+import org.apache.ace.deployment.verifier.VerifierService;
+import org.apache.ace.webui.UIExtensionFactory;
+import org.apache.felix.dm.DependencyActivatorBase;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.framework.BundleContext;
+
+public class Activator extends DependencyActivatorBase {
+
+	@Override
+	public void init(BundleContext context, DependencyManager manager)
+			throws Exception {
+		manager.add(createComponent().setInterface(
+                UIExtensionFactory.class.getName(), new Properties() {
+                    {
+                        put(UIExtensionFactory.EXTENSION_POINT_KEY, UIExtensionFactory.EXTENSION_POINT_VALUE_TARGET);
+                    }
+                }).setImplementation(ACEVerifierExtension.class)
+                .add(createServiceDependency()
+                		.setService(VerifierService.class)
+                		.setRequired(true))
+                .add(createServiceDependency()
+                        .setService(ConnectionFactory.class)
+                        .setRequired(true))
+                .add(createServiceDependency()
+                        .setService(DeploymentVersionRepository.class)
+                        .setRequired(true)
+                        ));
+	}
+
+	@Override
+	public void destroy(BundleContext context, DependencyManager manager)
+			throws Exception {
+		// TODO Auto-generated method stub
+		
+	}
+
+}

Added: ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/ui/VerificationResult.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/ui/VerificationResult.java?rev=1464402&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/ui/VerificationResult.java (added)
+++ ace/trunk/org.apache.ace.verifier/src/org/apache/ace/deployment/verifier/ui/VerificationResult.java Thu Apr  4 09:43:34 2013
@@ -0,0 +1,88 @@
+/*
+ * 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.ace.deployment.verifier.ui;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ace.deployment.verifier.VerifierService.VerifyEnvironment;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.wiring.BundleRevision;
+
+/**
+ * Provides the results of a verification.
+ */
+final class VerificationResult {
+    private final Set<String> m_customizers = new HashSet<String>();
+    private final Set<String> m_processors = new HashSet<String>();
+    private final Set<BundleRevision> m_bundles = new HashSet<BundleRevision>();
+    private final ByteArrayOutputStream m_output = new ByteArrayOutputStream();
+    
+    final PrintStream m_out = new PrintStream(m_output);
+
+    public void addBundle(VerifyEnvironment env, Map<String, String> manifest) throws BundleException {
+        m_bundles.add(env.addBundle(m_bundles.size(), manifest));
+    }
+
+    public void addCustomizer(String customizer) {
+        m_customizers.add(customizer.trim());
+    }
+
+    public void addProcessor(String processor) {
+        m_processors.add(processor.trim());
+    }
+
+    public boolean allCustomizerMatch() {
+        return m_customizers.containsAll(m_processors);
+    }
+
+    /**
+     * @return the bundles
+     */
+    public Set<BundleRevision> getBundles() {
+        return m_bundles;
+    }
+    
+    /**
+     * @return the customizers
+     */
+    public Set<String> getCustomizers() {
+        return m_customizers;
+    }
+    
+    /**
+     * @return the processors
+     */
+    public Set<String> getProcessors() {
+        return m_processors;
+    }
+    
+    public boolean hasCustomizers() {
+        return !m_customizers.isEmpty() || !m_processors.isEmpty();
+    }
+    
+    @Override
+    public String toString() {
+        return m_output.toString();
+    }
+}
\ No newline at end of file

Added: ace/trunk/org.apache.ace.verifier/src/org/apache/felix/framework/Logger.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.verifier/src/org/apache/felix/framework/Logger.java?rev=1464402&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.verifier/src/org/apache/felix/framework/Logger.java (added)
+++ ace/trunk/org.apache.ace.verifier/src/org/apache/felix/framework/Logger.java Thu Apr  4 09:43:34 2013
@@ -0,0 +1,324 @@
+/*
+ * 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.framework;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import org.osgi.framework.*;
+
+/**
+ * <p>
+ * This class mimics the standard OSGi <tt>LogService</tt> interface. An
+ * instance of this class is used by the framework for all logging. By default
+ * this class logs messages to standard out. The log level can be set to
+ * control the amount of logging performed, where a higher number results in
+ * more logging. A log level of zero turns off logging completely.
+ * </p>
+ * <p>
+ * The log levels match those specified in the OSGi Log Service (i.e., 1 = error,
+ * 2 = warning, 3 = information, and 4 = debug). The default value is 1.
+ * </p>
+ * <p>
+ * This class also uses the System Bundle's context to track log services
+ * and will use the highest ranking log service, if present, as a back end
+ * instead of printing to standard out. The class uses reflection to invoking
+ * the log service's method to avoid a dependency on the log interface.
+ * </p>
+**/
+public class Logger implements ServiceListener
+{
+    public static final int LOG_ERROR = 1;
+    public static final int LOG_WARNING = 2;
+    public static final int LOG_INFO = 3;
+    public static final int LOG_DEBUG = 4;
+
+    private int m_logLevel = 1;
+    private BundleContext m_context = null;
+
+    private final static int LOGGER_OBJECT_IDX = 0;
+    private final static int LOGGER_METHOD_IDX = 1;
+    private ServiceReference m_logRef = null;
+    private Object[] m_logger = null;
+
+    public Logger()
+    {
+    }
+
+    public final synchronized void setLogLevel(int i)
+    {
+        m_logLevel = i;
+    }
+
+    public final synchronized int getLogLevel()
+    {
+        return m_logLevel;
+    }
+
+    protected void setSystemBundleContext(BundleContext context)
+    {
+        // TODO: Find a way to log to a log service inside the framework.
+        // The issue is that we log messages while holding framework
+        // internal locks -- hence, when a log service calls back into 
+        // the framework (e.g., by loading a class) we might deadlock. 
+        // One instance of this problem is tracked in FELIX-536.
+        // For now we just disable logging to log services inside the
+        // framework. 
+
+        // m_context = context;
+        // startListeningForLogService();
+    }
+
+    public final void log(int level, String msg)
+    {
+        _log(null, null, level, msg, null);
+    }
+
+    public final void log(int level, String msg, Throwable throwable)
+    {
+        _log(null, null, level, msg, throwable);
+    }
+
+    public final void log(ServiceReference sr, int level, String msg)
+    {
+        _log(null, sr, level, msg, null);
+    }
+
+    public final void log(ServiceReference sr, int level, String msg, Throwable throwable)
+    {
+        _log(null, sr, level, msg, throwable);
+    }
+
+    public final void log(Bundle bundle, int level, String msg)
+    {
+        _log(bundle, null, level, msg, null);
+    }
+
+    public final void log(Bundle bundle, int level, String msg, Throwable throwable)
+    {
+        _log(bundle, null, level, msg, throwable);
+    }
+
+    protected void doLog(
+        Bundle bundle, ServiceReference sr, int level,
+        String msg, Throwable throwable)
+    {
+        String s = "";
+        if (sr != null)
+        {
+            s = s + "SvcRef "  + sr + " ";
+        }
+        else if (bundle != null)
+        {
+            s = s + "Bundle " + bundle.toString() + " ";
+        }
+        s = s + msg;
+        if (throwable != null)
+        {
+            s = s + " (" + throwable + ")";
+        }
+        switch (level)
+        {
+            case LOG_DEBUG:
+                System.out.println("DEBUG: " + s);
+                break;
+            case LOG_ERROR:
+                System.out.println("ERROR: " + s);
+                if (throwable != null)
+                {
+                    if ((throwable instanceof BundleException) &&
+                        (((BundleException) throwable).getNestedException() != null))
+                    {
+                        throwable = ((BundleException) throwable).getNestedException();
+                    }
+                    throwable.printStackTrace();
+                }
+                break;
+            case LOG_INFO:
+                System.out.println("INFO: " + s);
+                break;
+            case LOG_WARNING:
+                System.out.println("WARNING: " + s);
+                break;
+            default:
+                System.out.println("UNKNOWN[" + level + "]: " + s);
+        }
+    }
+
+    private void _log(
+        Bundle bundle, ServiceReference sr, int level,
+        String msg, Throwable throwable)
+    {
+        // Save our own copy just in case it changes. We could try to do
+        // more conservative locking here, but let's be optimistic.
+        Object[] logger = m_logger;
+
+        if (m_logLevel >= level)
+        {
+            // Use the log service if available.
+            if (logger != null)
+            {
+                _logReflectively(logger, sr, level, msg, throwable);
+            }
+            // Otherwise, default logging action.
+            else
+            {
+                doLog(bundle, sr, level, msg, throwable);
+            }
+        }
+    }
+
+    private void _logReflectively(
+        Object[] logger, ServiceReference sr, int level, String msg, Throwable throwable)
+    {
+        if (logger != null)
+        {
+            Object[] params = {
+                sr, new Integer(level), msg, throwable
+            };
+            try
+            {
+                ((Method) logger[LOGGER_METHOD_IDX]).invoke(logger[LOGGER_OBJECT_IDX], params);
+            }
+            catch (InvocationTargetException ex)
+            {
+                System.err.println("Logger: " + ex);
+            }
+            catch (IllegalAccessException ex)
+            {
+                System.err.println("Logger: " + ex);
+            }
+        }
+    }
+
+    /**
+     * This method is called when the system bundle context is set;
+     * it simply adds a service listener so that the system bundle can track
+     * log services to be used as the back end of the logging mechanism. It also
+     * attempts to get an existing log service, if present, but in general
+     * there will never be a log service present since the system bundle is
+     * started before every other bundle.
+    **/
+    private synchronized void startListeningForLogService()
+    {
+        // Add a service listener for log services.
+        try
+        {
+            m_context.addServiceListener(
+                this, "(objectClass=org.osgi.service.log.LogService)");
+        }
+        catch (InvalidSyntaxException ex) {
+            // This will never happen since the filter is hard coded.
+        }
+        // Try to get an existing log service.
+        m_logRef = m_context.getServiceReference("org.osgi.service.log.LogService");
+        // Get the service object if available and set it in the logger.
+        if (m_logRef != null)
+        {
+            setLogger(m_context.getService(m_logRef));
+        }
+    }
+
+    /**
+     * This method implements the callback for the ServiceListener interface.
+     * It is public as a byproduct of implementing the interface and should
+     * not be called directly. This method tracks run-time changes to log
+     * service availability. If the log service being used by the framework's
+     * logging mechanism goes away, then this will try to find an alternative.
+     * If a higher ranking log service is registered, then this will switch
+     * to the higher ranking log service.
+    **/
+    public final synchronized void serviceChanged(ServiceEvent event)
+    {
+        // If no logger is in use, then grab this one.
+        if ((event.getType() == ServiceEvent.REGISTERED) && (m_logRef == null))
+        {
+            m_logRef = event.getServiceReference();
+            // Get the service object and set it in the logger.
+            setLogger(m_context.getService(m_logRef));
+        }
+        // If a logger is in use, but this one has a higher ranking, then swap
+        // it for the existing logger.
+        else if ((event.getType() == ServiceEvent.REGISTERED) && (m_logRef != null))
+        {
+            ServiceReference ref =
+                m_context.getServiceReference("org.osgi.service.log.LogService");
+            if (!ref.equals(m_logRef))
+            {
+                m_context.ungetService(m_logRef);
+                m_logRef = ref;
+                setLogger(m_context.getService(m_logRef));
+            }
+
+        }
+        // If the current logger is going away, release it and try to
+        // find another one.
+        else if ((event.getType() == ServiceEvent.UNREGISTERING) &&
+            m_logRef.equals(event.getServiceReference()))
+        {
+            // Unget the service object.
+            m_context.ungetService(m_logRef);
+            // Try to get an existing log service.
+            m_logRef = m_context.getServiceReference(
+                "org.osgi.service.log.LogService");
+            // Get the service object if available and set it in the logger.
+            if (m_logRef != null)
+            {
+                setLogger(m_context.getService(m_logRef));
+            }
+            else
+            {
+                setLogger(null);
+            }
+        }
+    }
+
+    /**
+     * This method sets the new log service object. It also caches the method to
+     * invoke. The service object and method are stored in array to optimistically
+     * eliminate the need to locking when logging.
+    **/
+    public void setLogger(Object logObj)
+    {
+        if (logObj == null)
+        {
+            m_logger = null;
+        }
+        else
+        {
+            Class[] formalParams = {
+                ServiceReference.class,
+                Integer.TYPE,
+                String.class,
+                Throwable.class
+            };
+
+            try
+            {
+                Method logMethod = logObj.getClass().getMethod("log", formalParams);
+                logMethod.setAccessible(true);
+                m_logger = new Object[] { logObj, logMethod };
+            }
+            catch (NoSuchMethodException ex)
+            {
+                System.err.println("Logger: " + ex);
+                m_logger = null;
+            }
+        }
+    }
+}