Raw import of Bushel

git-svn-id: https://svn.apache.org/repos/asf/ant/ivy/core/trunk@1036848 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nicolas Lalevee 2010-11-19 14:06:06 +00:00
parent 5ca00743d5
commit ec958b5f6e
139 changed files with 238168 additions and 0 deletions

View File

@ -0,0 +1,25 @@
# ***************************************************************
# * 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.
# ***************************************************************
#Tue Aug 19 07:45:13 BST 2008
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
org.eclipse.jdt.core.compiler.compliance=1.5
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.5

View File

@ -0,0 +1,23 @@
# ***************************************************************
# * 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.
# ***************************************************************
#Tue Aug 19 07:45:14 BST 2008
eclipse.preferences.version=1
pluginProject.equinox=false
pluginProject.extensions=false
resolve.requirebundle=false

19
example/ant.properties Normal file
View File

@ -0,0 +1,19 @@
# ***************************************************************
# * 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.
# ***************************************************************
eclipse.home=/Developer/Applications/eclipse-3.5

22
example/build.properties Normal file
View File

@ -0,0 +1,22 @@
# ***************************************************************
# * 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.
# ***************************************************************
source.. = java/src/
output.. = eclipse/
bin.includes = META-INF/,\
.

114
example/build.xml Normal file
View File

@ -0,0 +1,114 @@
<!--
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.
-->
<project xmlns:ivy="antlib:org.apache.ivy.ant" name="osgi-example">
<loadproperties srcfile="ant.properties"/>
<property environment="env" />
<property name="artifact.version" value="1.0.0" />
<property name="artifact.name" value="com.acme.speedy" />
<property name="bundle.name" value="${artifact.name}-${artifact.version}" />
<property name="bundle.jar" value="${bundle.name}.jar" />
<property name="lib.dir" value="${basedir}/lib" />
<property name="target.dir" value="${basedir}/target" />
<property name="classes.dir" value="${basedir}/target/classes" />
<property name="jars.dir" value="${basedir}/target/jars" />
<property name="dist.dir" value="${basedir}/target/dist" />
<property name="bundle.dir" value="${basedir}/target/bundle" />
<property name="java-src.dir" value="${basedir}/java/src" />
<property name="osgi-main.jar" value="org.eclipse.osgi-3.5.0.v20090520.jar" />
<taskdef resource="org/apache/ivy/ant/antlib.xml" uri="antlib:org.apache.ivy.ant">
<classpath>
<fileset dir="${basedir}/lib" includes="org.apache.ivy*.jar" />
</classpath>
</taskdef>
<target name="check-eclipse-home">
<fail message="Please provide the eclipse home directory. Using -Declipse.home=/path/to/eclipse" unless="eclipse.home"/>
</target>
<target name="ivy-init" depends="check-eclipse-home">
<ivy:settings file="${basedir}/ivysettings.xml" />
<ivy:resolve file="${basedir}/ivy.xml" />
<ivy:cachepath pathid="dependency.classpath" conf="default" />
</target>
<target name="init">
<mkdir dir="${target.dir}" />
<mkdir dir="${classes.dir}" />
<mkdir dir="${jars.dir}" />
<mkdir dir="${dist.dir}" />
</target>
<target name="clean">
<delete dir="${target.dir}" />
</target>
<target name="clean-all" depends="clean">
<delete dir="${basedir}/.ivy" />
<delete dir="${basedir}/eclipse" />
</target>
<target name="compile" depends="init, ivy-init">
<javac debug="true"
debuglevel="source,lines,vars"
source="1.5"
target="1.5"
fork="true"
destdir="${classes.dir}"
srcdir="${java-src.dir}"
includeantruntime="false">
<classpath refid="dependency.classpath" />
<classpath>
<pathelement location="${classes.dir}" />
</classpath>
</javac>
</target>
<target name="jar" depends="compile">
<jar destfile="${jars.dir}/${bundle.jar}" basedir="${classes.dir}" manifest="META-INF/MANIFEST.MF" />
</target>
<target name="bundle" depends="jar">
<ivy:retrieve pattern="${bundle.dir}/lib/[artifact]-[revision].[ext]" sync="true" />
<mkdir dir="${bundle.dir}/config" />
<mkdir dir="${bundle.dir}/data" />
<copy file="${jars.dir}/${bundle.jar}" todir="${bundle.dir}/lib" />
<echo file="${bundle.dir}/config/config.ini">
osgi.bundles=org.eclipse.osgi.services-3.2.0.v20090520-1800.jar@start,${bundle.jar}@start
eclipse.ignoreApp=true
</echo>
</target>
<target name="run" depends="bundle">
<java fork="true" failonerror="true" maxmemory="128m" jar="${bundle.dir}/lib/${osgi-main.jar}" dir="${bundle.dir}">
<arg line="-consoleLog -debug -console -configuration ${bundle.dir}/config -data ${bundle.dir}/data -install ${bundle.dir}/lib" />
</java>
</target>
<target name="gen-run-sh" depends="bundle">
<echo file="${bundle.dir}/run.sh">
java -Xms128M -Xmx256M -jar ${bundle.dir}/lib/${osgi-main.jar} -consoleLog -debug -console -configuration ${bundle.dir}/config -data ${bundle.dir}/data -install ${bundle.dir}/lib
</echo>
<echo message="Run: ${bundle.dir}/run.sh"/>
</target>
</project>

29
example/ivy.xml Normal file
View File

@ -0,0 +1,29 @@
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="http://www.jaya.free.fr/ivyrep/ivy-doc.xsl"?>
<!--
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.
-->
<ivy-module version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
<info organisation="com.acme" module="speedy" manifest="META-INF/MANIFEST.MF" />
<configurations>
<conf name="compile" extends="default,embedded" />
<conf name="embedded" />
</configurations>
<dependencies>
</dependencies>
</ivy-module>

59
example/ivysettings.xml Normal file
View File

@ -0,0 +1,59 @@
<!--
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.
-->
<ivysettings>
<!--
<typedef name="osgi-parser" classname="org.apache.ivy.osgi.repo.ManifestMDParser" />
<typedef name="osgi-bundlerepo" classname="org.apache.ivy.osgi.repo.BundleRepoResolver" />
<typedef name="ivy-profile-provider" classname="org.apache.ivy.osgi.repo.osgi.ExecutionEnvironmentProfileProvider" />
-->
<typedef name="osgi-ivy-parser" classname="org.apache.ivy.osgi.ivy.OsgiIvyParser" />
<typedef name="osgi-manifest-parser" classname="org.apache.ivy.osgi.ivy.OsgiManifestParser" />
<typedef name="osgi-file-resolver" classname="org.apache.ivy.osgi.ivy.OsgiFileResolver" />
<typedef name="osgi-revision" classname="org.apache.ivy.osgi.ivy.OsgiRevisionStrategy" />
<settings defaultResolver="local" defaultLatestStrategy="osgi-revision" />
<caches resolutionCacheDir="${ivy.settings.dir}/cache/resolution" useOrigin="true">
<cache name="localcache" basedir="${basedir}/.ivy/local-cache">
<ttl duration="0d" />
</cache>
</caches>
<parsers>
<osgi-ivy-parser />
<osgi-manifest-parser/>
</parsers>
<resolvers>
<!--
<osgi-file name="local" repoXmlFile="${ivy.settings.dir}/repo-eclipse.xml">
<osgi-profileProvider />
</osgi-file>
-->
<osgi-file-resolver name="local">
<ivy pattern="${eclipse.home}/plugins/[organisation].[module]_[revision].jar" />
<artifact pattern="${eclipse.home}/plugins/[organisation].[module]_[revision].jar" />
</osgi-file-resolver>
</resolvers>
<latest-strategies>
<osgi-revision name="osgi-revision" />
</latest-strategies>
</ivysettings>

View File

@ -0,0 +1,70 @@
/*
* 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 com.acme.speedy;
import java.util.Hashtable;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.util.tracker.ServiceTracker;
public class Activator implements BundleActivator {
private ServiceTracker simpleLogServiceTracker;
private SimpleLogService simpleLogService;
/*
* (non-Javadoc)
* @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext context) throws Exception {
// register the service
context.registerService(
SimpleLogService.class.getName(),
new SimpleLogServiceImpl(),
new Hashtable());
// create a tracker and track the log service
simpleLogServiceTracker =
new ServiceTracker(context, SimpleLogService.class.getName(), null);
simpleLogServiceTracker.open();
// grab the service
simpleLogService = (SimpleLogService) simpleLogServiceTracker.getService();
if(simpleLogService != null)
simpleLogService.log("Andale! Andale! Arriba! Arriba! Yii-hah!");
}
/*
* (non-Javadoc)
* @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext context) throws Exception {
if(simpleLogService != null)
simpleLogService.log("Gracias, Adios! Hasta la vista! YEE-HEE!!!");
// close the service tracker
simpleLogServiceTracker.close();
simpleLogServiceTracker = null;
simpleLogService = null;
}
}

View File

@ -0,0 +1,24 @@
/*
* 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 com.acme.speedy;
public interface SimpleLogService {
public void log(String message);
}

View File

@ -0,0 +1,26 @@
/*
* 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 com.acme.speedy;
public class SimpleLogServiceImpl implements SimpleLogService {
public void log(String message) {
System.out.println(message);
}
}

View File

@ -0,0 +1,21 @@
# ***************************************************************
# * 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.
# ***************************************************************
source.. = src/
bin.includes = META-INF/,\
.

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<project name="myplugin">
<import file="../common-build/build-eclipse-plugin.xml" />
</project>

View File

@ -0,0 +1,32 @@
<?xml version="1.0"?>
<!--
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.
-->
<ivy-module version="2.0">
<info organisation="com.acme" module="myplugin" manifest="META-INF/MANIFEST.MF" />
<configurations>
<conf name="compile" extends="default,embedded" description="Dependencies for the compilation" />
<conf name="embedded" description="Dependencies embedded into the plugin's jar" />
</configurations>
<dependencies>
<!-- exemple of a dependency that we can't declare in the MANIFEST.MF because we want it to be embedded -->
<!--dependency osgi="bundle" org="" module="org.apache.commons.httpcore" rev="4.1.0" conf="embedded->default" /-->
<!-- Ivy-Osgi doesn't understand bundle fragment -->
<dependency osgi="bundle" org="" name="org.eclipse.swt.cocoa.macosx" rev="3.+" />
</dependencies>
</ivy-module>

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<!--
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.
-->
<plugin>
<extension
point="org.eclipse.ui.actionSets">
<actionSet
label="Sample Action Set"
visible="true"
id="com.acme.helloworld.actionSet">
<menu
label="Sample &amp;Menu"
id="sampleMenu">
<separator
name="sampleGroup">
</separator>
</menu>
<action
label="&amp;Sample Action"
icon="icons/sample.gif"
class="com.acme.helloworld.actions.helloWorldAction"
tooltip="Hello, Eclipse world"
menubarPath="sampleMenu/sampleGroup"
toolbarPath="sampleGroup"
id="com.acme.helloworld.actions.helloWorldAction">
</action>
</actionSet>
</extension>
</plugin>

View File

@ -0,0 +1,78 @@
/*
* 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 com.acme.helloworld;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
/**
* The activator class controls the plug-in life cycle
*/
public class Activator extends AbstractUIPlugin {
// The plug-in ID
public static final String PLUGIN_ID = "com.acme.helloworld";
// The shared instance
private static Activator plugin;
/**
* The constructor
*/
public Activator() {
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext context) throws Exception {
plugin = null;
super.stop(context);
}
/**
* Returns the shared instance
*
* @return the shared instance
*/
public static Activator getDefault() {
return plugin;
}
/**
* Returns an image descriptor for the image file at the given
* plug-in relative path
*
* @param path the path
* @return the image descriptor
*/
public static ImageDescriptor getImageDescriptor(String path) {
return imageDescriptorFromPlugin(PLUGIN_ID, path);
}
}

View File

@ -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 com.acme.helloworld.actions;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
import org.eclipse.jface.dialogs.MessageDialog;
/**
* Our sample action implements workbench action delegate.
* The action proxy will be created by the workbench and
* shown in the UI. When the user tries to use the action,
* this delegate will be created and execution will be
* delegated to it.
* @see IWorkbenchWindowActionDelegate
*/
public class helloWorldAction implements IWorkbenchWindowActionDelegate {
private IWorkbenchWindow window;
/**
* The constructor.
*/
public helloWorldAction() {
}
/**
* The action has been activated. The argument of the
* method represents the 'real' action sitting
* in the workbench UI.
* @see IWorkbenchWindowActionDelegate#run
*/
public void run(IAction action) {
MessageDialog.openInformation(
window.getShell(),
"Helloworld",
"Hello, Eclipse world");
}
/**
* Selection in the workbench has been changed. We
* can change the state of the 'real' action here
* if we want, but this can only happen after
* the delegate has been created.
* @see IWorkbenchWindowActionDelegate#selectionChanged
*/
public void selectionChanged(IAction action, ISelection selection) {
}
/**
* We can use this method to dispose of any system
* resources we previously allocated.
* @see IWorkbenchWindowActionDelegate#dispose
*/
public void dispose() {
}
/**
* We will cache window object in order to
* be able to provide parent shell for the message dialog.
* @see IWorkbenchWindowActionDelegate#init
*/
public void init(IWorkbenchWindow window) {
this.window = window;
}
}

View File

@ -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.
-->
<project name="common-build" xmlns:ivy="ivy">
<dirname property="commondir" file="${ant.file.common-build}" />
<!-- Load Ivy ant tasks -->
<path id="antlib.classpath">
<fileset dir="${commondir}/lib">
<include name="*.jar" />
</fileset>
</path>
<taskdef uri="ivy" resource="org/apache/ivy/ant/antlib.xml" classpathref="antlib.classpath" />
<!-- Load the properties where is defined the eclipse home -->
<property file="${commondir}/ivysettings.properties" />
<target name="clean" description="Clean the build directory">
<delete dir="${basedir}/target" />
</target>
<target name="obrindex" description="Build the obr index">
<!-- build the repo.xml which aggregate every metadata of the Eclipse plugins -->
<ivy:buildobr baseDir="${eclipse.home}" basePath="${eclipse.home}" out="${commondir}/repo-eclipse.xml" indent="true" />
</target>
<target name="ivy:configure">
<!-- classical ivy configuration -->
<ivy:configure file="${commondir}/ivysettings.xml" />
</target>
<target name="ivy:resolve" depends="ivy:configure">
<!-- classical resolve and cache-path -->
<ivy:resolve file="ivy.xml" conf="*" />
<ivy:cachepath pathid="compile.classpath" conf="default" useOrigin="true" />
</target>
<target name="compile" depends="ivy:resolve" description="Compile the Eclipse plugin">
<mkdir dir="${basedir}/target/classes" />
<!-- simple javac (WARNING: contrary to the JDT, javac doesn't understand OSGi's accessibility (private packages)) -->
<javac srcdir="${basedir}/src" classpathref="compile.classpath" destdir="${basedir}/target/classes" debug="true" includeAntRuntime="false" />
<copy todir="${basedir}/target/classes">
<fileset dir="${basedir}/src">
<include name="**" />
<exclude name="**/*.java" />
<exclude name="**/package.html" />
</fileset>
<fileset dir="${basedir}">
<include name="plugin.xml" />
</fileset>
</copy>
</target>
<target name="build" depends="compile" description="Build the Eclipse plugin">
<!-- simple jaring -->
<jar basedir="${basedir}/target/classes" destfile="${basedir}/target/${ant.project.name}.jar" manifest="META-INF/MANIFEST.MF" />
</target>
</project>

View File

@ -0,0 +1,21 @@
# ***************************************************************
# * 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.
# ***************************************************************
# Unix users, set it to something like: /home/me/tools/eclipse-3.4/plugins/
# Windows users, it should look like: D:/tools/eclipse-3.4/plugins/ or D:\\tools\\eclipse-3.4\\plugins\\
eclipse.home=/home/me/tools/eclipse-3.5/plugins/

View File

@ -0,0 +1,63 @@
<!--
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.
-->
<ivysettings>
<!-- Load the properties where is defined the eclipse location -->
<properties file="ivysettings.properties" />
<!-- We need some custom types -->
<!-- The parser of MANIFEST.MF -->
<typedef name="osgi-parser" classname="org.apache.ivy.osgi.repo.ManifestMDParser" />
<!-- The parser of ivy.xml that can reference a MANIFEST.MF-->
<typedef name="osgi-ivyparser" classname="org.apache.ivy.osgi.ivy.OsgiIvyParser" />
<!-- The Ivy Osgi repo resolver -->
<typedef name="osgi-repo" classname="org.apache.ivy.osgi.repo.BundleRepoResolver" />
<!-- Ivy Osgi's latest startegy -->
<typedef name="osgi-latest" classname="org.apache.ivy.osgi.ivy.OsgiRevisionStrategy" />
<!-- Ivy's default provider of OSGi execution environement profiles -->
<typedef name="osgi-profileProvider" classname="org.apache.ivy.osgi.repo.osgi.ExecutionEnvironmentProfileProvider" />
<!-- We will use Ivy Osgi's latest strategy -->
<latest-strategies>
<osgi-latest name="osgi-latest-revision" />
</latest-strategies>
<!-- We will use Ivy Osgi's parsers -->
<parsers>
<osgi-ivyparser />
<osgi-parser>
<osgi-profileProvider />
</osgi-parser>
</parsers>
<!-- We need to define the Ivy Osgi latest strategy as the default one -->
<settings defaultResolver="eclipse" defaultLatestStrategy="osgi-latest-revision" />
<!-- These are usual cache setup -->
<caches resolutionCacheDir="${ivy.settings.dir}/cache/resolution" useOrigin="true">
<cache name="eclipse" basedir="${ivy.settings.dir}/cache/eclipse" />
</caches>
<!-- We just need to define our Ivy OSGi resolver -->
<resolvers>
<osgi-repo name="eclipse" repoXmlFile="${ivy.settings.dir}/repo-eclipse.xml">
<osgi-profileProvider />
</osgi-repo>
</resolvers>
</ivysettings>

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<project name="com.acme.mywebapp">
<import file="${basedir}/../common-build/build-osgi.xml" />
</project>

View File

@ -0,0 +1,56 @@
/*
* 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 com.acme.mywebapp;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloOsgiWorldServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
addHelloWorld(resp, req.getMethod());
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
addHelloWorld(resp, req.getMethod());
}
@Override
public String getServletInfo() {
return "Simple Osgi World Servlet";
}
private void addHelloWorld(HttpServletResponse response, String method) throws IOException {
response.setContentType("text/html");
ServletOutputStream out = response.getOutputStream();
out.println("<html>");
out.println("<head><title>Hello Osgi World</title></head>");
out.println("<body>");
out.println("<h1>Hello OSGi World</h1>");
out.println("<h2>http method used:" + method + "</h2>");
out.println("</body></html>");
}
}

View File

@ -0,0 +1,67 @@
<!--
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.
-->
<project name="common-build" xmlns:ivy="ivy">
<dirname property="commondir" file="${ant.file.common-build}" />
<!-- Load Ivy ant tasks -->
<path id="antlib.classpath">
<fileset dir="${commondir}/lib">
<include name="*.jar" />
</fileset>
</path>
<taskdef uri="ivy" resource="org/apache/ivy/ant/antlib.xml" classpathref="antlib.classpath" />
<target name="clean" description="Clean the build directory">
<delete dir="${basedir}/target" />
</target>
<target name="ivy:configure">
<!-- classical ivy configuration -->
<ivy:configure file="${commondir}/ivysettings.xml" />
</target>
<target name="ivy:resolve" depends="ivy:configure">
<!-- the ivy file here is the manifest -->
<ivy:resolve file="META-INF/MANIFEST.MF" conf="*" />
<ivy:cachepath pathid="compile.classpath" conf="default" useOrigin="true" />
</target>
<target name="compile" depends="ivy:resolve" description="Compile the OSGi bundle">
<mkdir dir="${basedir}/target/classes" />
<!-- simple javac (WARNING: contrary to the JDT, javac doesn't understand OSGi's accessibility (private packages)) -->
<javac srcdir="${basedir}/src" classpathref="compile.classpath" destdir="${basedir}/target/classes" debug="true" includeAntRuntime="false" />
<copy todir="${basedir}/target/classes">
<fileset dir="${basedir}/src">
<include name="**" />
<exclude name="**/*.java" />
<exclude name="**/package.html" />
</fileset>
<fileset dir="${basedir}">
<include name="plugin.xml" />
</fileset>
</copy>
</target>
<target name="build" depends="compile" description="Build the Eclipse plugin">
<!-- simple jaring -->
<jar basedir="${basedir}/target/classes" destfile="${basedir}/target/${ant.project.name}.jar" manifest="META-INF/MANIFEST.MF" />
</target>
</project>

View File

@ -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.
-->
<ivysettings>
<!-- We need some custom types -->
<!-- The parser of MANIFEST.MF -->
<typedef name="osgi-parser" classname="org.apache.ivy.osgi.repo.ManifestMDParser" />
<!-- The parser of ivy.xml that can reference a MANIFEST.MF-->
<typedef name="osgi-ivyparser" classname="org.apache.ivy.osgi.ivy.OsgiIvyParser" />
<!-- The Ivy Osgi repo resolver -->
<typedef name="osgi-repo" classname="org.apache.ivy.osgi.repo.BundleRepoResolver" />
<!-- Ivy Osgi's latest startegy -->
<typedef name="osgi-latest" classname="org.apache.ivy.osgi.ivy.OsgiRevisionStrategy" />
<!-- Ivy's default provider of OSGi execution environement profiles -->
<typedef name="osgi-profileProvider" classname="org.apache.ivy.osgi.repo.osgi.ExecutionEnvironmentProfileProvider" />
<!-- We will use Ivy Osgi's latest strategy -->
<latest-strategies>
<osgi-latest name="osgi-latest-revision" />
</latest-strategies>
<!-- We will use Ivy Osgi's parsers -->
<parsers>
<osgi-ivyparser />
<osgi-parser>
<osgi-profileProvider />
</osgi-parser>
</parsers>
<!-- We need to define the Ivy Osgi latest strategy as the default one -->
<settings defaultResolver="osgi-bundles" defaultLatestStrategy="osgi-latest-revision" />
<!-- These are usual cache setup -->
<caches resolutionCacheDir="${ivy.settings.dir}/cache/resolution" useOrigin="true">
<cache name="osgi-bundles" basedir="${ivy.settings.dir}/cache/osgi-bundles" />
</caches>
<!-- We just need to define our Ivy Osgi resolver -->
<resolvers>
<osgi-repo name="osgi-bundles" repoXmlFile="${ivy.settings.dir}/../repo/repo.xml">
<osgi-profileProvider />
</osgi-repo>
</resolvers>
</ivysettings>

View File

@ -0,0 +1,31 @@
<!--
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.
-->
<project name="repo-build" default="build" xmlns:ivy="ivy">
<!-- we need at least ivy tasks definitions -->
<import file="${basedir}/../common-build/build-osgi.xml" />
<target name="build">
<ivy:configure file="ivysettings.xml" />
<ivy:resolve file="ivy.xml" conf="*" />
<ivy:retrieve pattern="[artifact]_[revision].[ext]" type="jar" />
<ivy:buildobr baseDir="${basedir}/" basePath="${basedir}/" out="${basedir}/repo.xml" indent="true" />
</target>
</project>

View File

@ -0,0 +1,24 @@
<!--
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.
-->
<ivy-module version="2.0">
<info organisation="com.acme" module="local-osgi-repo" />
<dependencies>
<dependency org="javax.servlet" name="com.springsource.javax.servlet" rev="2.4.0" />
</dependencies>
</ivy-module>

View File

@ -0,0 +1,41 @@
<!--
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.
-->
<ivysettings>
<settings defaultResolver="com.springsource.repository.bundles" />
<resolvers>
<url name="com.springsource.repository.bundles.release">
<ivy
pattern="http://repository.springsource.com/ivy/bundles/release/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
<artifact
pattern="http://repository.springsource.com/ivy/bundles/release/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
</url>
<url name="com.springsource.repository.bundles.external">
<ivy
pattern="http://repository.springsource.com/ivy/bundles/external/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
<artifact
pattern="http://repository.springsource.com/ivy/bundles/external/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
</url>
<chain name="com.springsource.repository.bundles" returnFirst="true">
<resolver ref="com.springsource.repository.bundles.release" />
<resolver ref="com.springsource.repository.bundles.external" />
</chain>
</resolvers>
</ivysettings>

View File

@ -0,0 +1,193 @@
/*
* 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.ivy.osgi.ant;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.xml.transform.TransformerConfigurationException;
import org.apache.ivy.Ivy;
import org.apache.ivy.ant.AntMessageLogger;
import org.apache.ivy.ant.IvyTask;
import org.apache.ivy.core.IvyContext;
import org.apache.ivy.core.cache.DefaultRepositoryCacheManager;
import org.apache.ivy.core.cache.RepositoryCacheManager;
import org.apache.ivy.core.settings.IvySettings;
import org.apache.ivy.osgi.obr.xml.OBRXMLWriter;
import org.apache.ivy.osgi.repo.FSManifestIterable;
import org.apache.ivy.osgi.repo.ManifestAndLocation;
import org.apache.ivy.osgi.repo.ResolverManifestIterable;
import org.apache.ivy.plugins.resolver.BasicResolver;
import org.apache.ivy.plugins.resolver.DependencyResolver;
import org.apache.ivy.util.Message;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
public class BuildBundleRepoDescriptorTask extends IvyTask {
private String resolverName = null;
private File file = null;
private String cacheName = null;
private String encoding = "UTF-8";
private boolean indent = true;
private File baseDir;
private String basePath = "";
private boolean quiet;
public void setResolver(String resolverName) {
this.resolverName = resolverName;
}
public void setCache(String cacheName) {
this.cacheName = cacheName;
}
public void setOut(File file) {
this.file = file;
}
public void setEncoding(String encoding) {
this.encoding = encoding;
}
public void setIndent(boolean indent) {
this.indent = indent;
}
public void setBaseDir(File dir) {
this.baseDir = dir;
}
public void setBasePath(String basePath) {
this.basePath = basePath;
}
public void setQuiet(boolean quiet) {
this.quiet = quiet;
}
@Override
protected void prepareTask() {
if (baseDir == null) {
super.prepareTask();
}
}
@Override
public void doExecute() throws BuildException {
if (file == null) {
throw new BuildException("No output file specified: use the attribute 'out'");
}
Iterable<ManifestAndLocation> it;
if (resolverName != null) {
if (baseDir != null) {
throw new BuildException("specify only one of 'resolver' or 'baseDir'");
}
if (cacheName != null) {
throw new BuildException("specify only one of 'resolver' or 'cache'");
}
if (basePath != null) {
log("'basePath' is only usefull with 'baseDir'", Project.MSG_WARN);
}
Ivy ivy = getIvyInstance();
IvySettings settings = ivy.getSettings();
DependencyResolver resolver = settings.getResolver(resolverName);
if (resolver == null) {
throw new BuildException("the resolver '" + resolverName + "' was not found");
}
if (!(resolver instanceof BasicResolver)) {
throw new BuildException("the type of resolver '" + resolver.getClass().getCanonicalName()
+ "' is not supported.");
}
it = new ResolverManifestIterable((BasicResolver) resolver);
} else if (baseDir != null) {
if (cacheName != null) {
throw new BuildException("specify only one of 'baseDir' or 'cache'");
}
if (!baseDir.isDirectory()) {
throw new BuildException(baseDir + " is not a directory");
}
it = new FSManifestIterable(baseDir, basePath);
} else if (cacheName != null) {
Ivy ivy = getIvyInstance();
RepositoryCacheManager cacheManager = ivy.getSettings().getRepositoryCacheManager(cacheName);
if (!(cacheManager instanceof DefaultRepositoryCacheManager)) {
throw new BuildException("the type of cache '" + cacheManager.getClass().getCanonicalName()
+ "' is not supported.");
}
File basedir = ((DefaultRepositoryCacheManager) cacheManager).getBasedir();
it = new FSManifestIterable(basedir, basedir.getAbsolutePath() + File.separator);
} else {
throw new BuildException("No resolver, cache or basedir specified: "
+ "please provide one of them through the attribute 'resolver', 'cache' or 'dir'");
}
OutputStream out;
try {
out = new FileOutputStream(file);
} catch (FileNotFoundException e) {
throw new BuildException(file + " was not found", e);
}
ContentHandler hd;
try {
hd = OBRXMLWriter.newHandler(out, encoding, indent);
} catch (TransformerConfigurationException e) {
throw new BuildException("Sax configuration error: " + e.getMessage(), e);
}
class AntMessageLogger2 extends AntMessageLogger {
AntMessageLogger2() {
super(BuildBundleRepoDescriptorTask.this);
}
}
IvyContext.getContext().getMessageLogger();
Message.setDefaultLogger(new AntMessageLogger2());
try {
OBRXMLWriter.writeManifests(it, hd, quiet);
} catch (SAXException e) {
throw new BuildException("Sax serialisation error: " + e.getMessage(), e);
}
try {
out.flush();
out.close();
} catch (IOException e) {
// don't care
}
Message.sumupProblems();
}
}

View File

@ -0,0 +1,90 @@
/*
* 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.ivy.osgi.ant;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.ParseException;
import java.util.jar.Manifest;
import org.apache.ivy.ant.IvyTask;
import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
import org.apache.ivy.osgi.core.BundleInfo;
import org.apache.ivy.osgi.core.ManifestParser;
import org.apache.ivy.osgi.repo.BundleInfoAdapter;
import org.apache.ivy.osgi.repo.osgi.ExecutionEnvironmentProfileProvider;
import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorWriter;
import org.apache.tools.ant.BuildException;
public class ConvertManifestTask extends IvyTask {
private File manifest = null;
private File ivyFile = null;
private ExecutionEnvironmentProfileProvider profileProvider;
public void setProfileProvider(ExecutionEnvironmentProfileProvider profileProvider) {
this.profileProvider = profileProvider;
}
public void setManifest(File manifest) {
this.manifest = manifest;
}
public void setIvyFile(File ivyFile) {
this.ivyFile = ivyFile;
}
@Override
public void doExecute() throws BuildException {
if (ivyFile == null) {
throw new BuildException("destination ivy file is required for convertmanifest task");
}
if (manifest == null) {
throw new BuildException("source manifest file is required for convertmanifest task");
}
Manifest m;
try {
m = new Manifest(new FileInputStream(manifest));
} catch (FileNotFoundException e) {
throw new BuildException("the manifest file '" + manifest + "' was not found", e);
} catch (IOException e) {
throw new BuildException("the manifest file '" + manifest + "' could not be read", e);
}
BundleInfo bundleInfo;
try {
bundleInfo = ManifestParser.parseManifest(m);
} catch (ParseException e) {
throw new BuildException("Incorrect manifest file '" + manifest + "'", e);
}
ModuleDescriptor md = BundleInfoAdapter.toModuleDescriptor(bundleInfo, profileProvider);
try {
XmlModuleDescriptorWriter.write(md, ivyFile);
} catch (IOException e) {
throw new BuildException("The ivyFile '" + ivyFile + "' could not be written", e);
}
}
}

View File

@ -0,0 +1,23 @@
<?xml version="1.0"?>
<!--
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.
-->
<antlib xmlns:current="ant:current">
<taskdef name="buildobr" classname="org.apache.ivy.osgi.ant.BuildBundleRepoDescriptorTask" />
<taskdef name="convertmanifest" classname="org.apache.ivy.osgi.ant.ConvertManifestTask" />
</antlib>

View File

@ -0,0 +1,95 @@
/*
* 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.ivy.osgi.core;
import org.apache.ivy.osgi.util.Version;
public class BundleCapability {
private final String name;
private final Version version;
private final String type;
public BundleCapability(String type, String name, Version version) {
this.type = type;
this.name = name;
this.version = version;
}
public String getType() {
return type;
}
public String getName() {
return name;
}
public Version getVersion() {
return version;
}
public Version getRawVersion() {
return version;
}
@Override
public String toString() {
return name + (version == null ? "" : ";" + version);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((version == null) ? 0 : version.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof BundleCapability)) {
return false;
}
BundleCapability other = (BundleCapability) obj;
if (name == null) {
if (other.name != null) {
return false;
}
} else if (!name.equals(other.name)) {
return false;
}
if (version == null) {
if (other.version != null) {
return false;
}
} else if (!version.equals(other.version)) {
return false;
}
return true;
}
}

View File

@ -0,0 +1,286 @@
/*
* 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.ivy.osgi.core;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.apache.ivy.osgi.util.Version;
/**
* Bundle info extracted from the bundle manifest.
*
*/
public class BundleInfo {
public static final Version DEFAULT_VERSION = new Version(1, 0, 0, null);
public static final String PACKAGE_TYPE = "package";
public static final String BUNDLE_TYPE = "bundle";
public static final String SERVICE_TYPE = "service";
private String symbolicName;
private String presentationName;
private String id;
private Version version;
private Set<BundleRequirement> requirements = new LinkedHashSet<BundleRequirement>();
private Set<BundleCapability> capabilities = new LinkedHashSet<BundleCapability>();
private List<String> executionEnvironments = Collections.emptyList();
private String description;
private String documentation;
private String license;
private Integer size;
private String uri;
public BundleInfo(String name, Version version) {
this.symbolicName = name;
this.version = version;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("BundleInfo [executionEnvironments=");
builder.append(executionEnvironments);
builder.append(", capabilities=");
builder.append(capabilities);
builder.append(", requirements=");
builder.append(requirements);
builder.append(", symbolicName=");
builder.append(symbolicName);
builder.append(", version=");
builder.append(version);
builder.append("]");
return builder.toString();
}
public String getSymbolicName() {
return symbolicName;
}
public Version getVersion() {
return version == null ? DEFAULT_VERSION : version;
}
public Version getRawVersion() {
return version;
}
public void setUri(String uri) {
this.uri = uri;
}
public String getUri() {
return uri;
}
public void setId(String id) {
this.id = id;
}
public String getId() {
return id;
}
public void setPresentationName(String presentationName) {
this.presentationName = presentationName;
}
public String getPresentationName() {
return presentationName;
}
public void setDescription(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
public void setDocumentation(String documentation) {
this.documentation = documentation;
}
public String getDocumentation() {
return documentation;
}
public void setLicense(String license) {
this.license = license;
}
public String getLicense() {
return license;
}
public void setSize(Integer size) {
this.size = size;
}
public Integer getSize() {
return size;
}
public void addRequirement(BundleRequirement requirement) {
requirements.add(requirement);
}
public Set<BundleRequirement> getRequirements() {
return requirements;
}
public void addCapability(BundleCapability capability) {
capabilities.add(capability);
}
public Set<BundleCapability> getCapabilities() {
return capabilities;
}
public List<String> getExecutionEnvironments() {
return executionEnvironments;
}
public void setExecutionEnvironments(List<String> executionEnvironment) {
this.executionEnvironments = executionEnvironment;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((capabilities == null) ? 0 : capabilities.hashCode());
result = prime * result + ((requirements == null) ? 0 : requirements.hashCode());
result = prime * result + ((symbolicName == null) ? 0 : symbolicName.hashCode());
result = prime * result + ((version == null) ? 0 : version.hashCode());
result = prime * result + ((executionEnvironments == null) ? 0 : executionEnvironments.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof BundleInfo)) {
return false;
}
BundleInfo other = (BundleInfo) obj;
if (capabilities == null) {
if (other.capabilities != null) {
return false;
}
} else if (!capabilities.equals(other.capabilities)) {
return false;
}
if (requirements == null) {
if (other.requirements != null) {
return false;
}
} else if (!requirements.equals(other.requirements)) {
return false;
}
if (symbolicName == null) {
if (other.symbolicName != null) {
return false;
}
} else if (!symbolicName.equals(other.symbolicName)) {
return false;
}
if (version == null) {
if (other.version != null) {
return false;
}
} else if (!version.equals(other.version)) {
return false;
}
if (executionEnvironments == null) {
if (other.executionEnvironments != null) {
return false;
}
} else if (!executionEnvironments.equals(other.executionEnvironments)) {
return false;
}
return true;
}
@Deprecated
public Set<BundleRequirement> getRequires() {
Set<BundleRequirement> set = new LinkedHashSet<BundleRequirement>();
for (BundleRequirement requirement : requirements) {
if (requirement.getType().equals(BUNDLE_TYPE)) {
set.add(requirement);
}
}
return set;
}
@Deprecated
public Set<BundleRequirement> getImports() {
Set<BundleRequirement> set = new LinkedHashSet<BundleRequirement>();
for (BundleRequirement requirement : requirements) {
if (requirement.getType().equals(PACKAGE_TYPE)) {
set.add(requirement);
}
}
return set;
}
@Deprecated
public Set<ExportPackage> getExports() {
Set<ExportPackage> set = new LinkedHashSet<ExportPackage>();
for (BundleCapability capability : capabilities) {
if (capability.getType().equals(PACKAGE_TYPE)) {
set.add((ExportPackage) capability);
}
}
return set;
}
@Deprecated
public Set<BundleCapability> getServices() {
Set<BundleCapability> set = new LinkedHashSet<BundleCapability>();
for (BundleCapability capability : capabilities) {
if (capability.getType().equals(SERVICE_TYPE)) {
set.add(capability);
}
}
return set;
}
}

View File

@ -0,0 +1,113 @@
/*
* 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.ivy.osgi.core;
import org.apache.ivy.osgi.util.VersionRange;
public class BundleRequirement {
private final String name;
private final String resolution;
private final VersionRange version;
private final String type;
public BundleRequirement(String type, String name, VersionRange version, String resolution) {
this.type = type;
this.name = name;
this.version = version;
this.resolution = resolution;
}
public String getType() {
return type;
}
public String getName() {
return name;
}
public VersionRange getVersion() {
return version;
}
public String getResolution() {
return resolution;
}
@Override
public String toString() {
return name + (version == null ? "" : ";" + version) + (resolution == null ? "" : " (" + resolution + ")");
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((type == null) ? 0 : type.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((resolution == null) ? 0 : resolution.hashCode());
result = prime * result + ((version == null) ? 0 : version.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof BundleRequirement)) {
return false;
}
BundleRequirement other = (BundleRequirement) obj;
if (type == null) {
if (other.type != null) {
return false;
}
} else if (!type.equals(other.type)) {
return false;
}
if (name == null) {
if (other.name != null) {
return false;
}
} else if (!name.equals(other.name)) {
return false;
}
if (resolution == null) {
if (other.resolution != null) {
return false;
}
} else if (!resolution.equals(other.resolution)) {
return false;
}
if (version == null) {
if (other.version != null) {
return false;
}
} else if (!version.equals(other.version)) {
return false;
}
return true;
}
}

View File

@ -0,0 +1,74 @@
/*
* 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.ivy.osgi.core;
import java.util.HashSet;
import java.util.Set;
import org.apache.ivy.osgi.util.Version;
public class ExportPackage extends BundleCapability {
private final Set<String> uses = new HashSet<String>();
public ExportPackage(String name, Version version) {
super(BundleInfo.PACKAGE_TYPE, name, version);
}
public void addUse(String pkg) {
uses.add(pkg);
}
@Override
public Version getVersion() {
return super.getVersion() == null ? BundleInfo.DEFAULT_VERSION : super.getVersion();
}
public Set<String> getUses() {
return uses;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((uses == null) ? 0 : uses.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
ExportPackage other = (ExportPackage) obj;
if (uses == null) {
if (other.uses != null) {
return false;
}
} else if (!uses.equals(other.uses)) {
return false;
}
return true;
}
}

View File

@ -0,0 +1,113 @@
/*
* 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.ivy.osgi.core;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class ManifestHeaderElement {
private List<String> values = new ArrayList<String>();
private Map<String, String> attributes = new HashMap<String, String>();
private Map<String, String> directives = new HashMap<String, String>();
public List<String> getValues() {
return values;
}
public void addValue(String value) {
values.add(value);
}
public Map<String, String> getAttributes() {
return attributes;
}
public void addAttribute(String name, String value) {
attributes.put(name, value);
}
public Map<String, String> getDirectives() {
return directives;
}
public void addDirective(String name, String value) {
directives.put(name, value);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ManifestHeaderElement)) {
return false;
}
ManifestHeaderElement other = (ManifestHeaderElement) obj;
if (other.values.size() != values.size()) {
return false;
}
for (String value : values) {
if (!other.values.contains(value)) {
return false;
}
}
if (other.directives.size() != directives.size()) {
return false;
}
for (Entry<String, String> directive : directives.entrySet()) {
if (!directive.getValue().equals(other.directives.get(directive.getKey()))) {
return false;
}
}
if (other.attributes.size() != attributes.size()) {
return false;
}
for (Entry<String, String> attribute : attributes.entrySet()) {
if (!attribute.getValue().equals(other.attributes.get(attribute.getKey()))) {
return false;
}
}
return true;
}
@Override
public String toString() {
String string = "";
Iterator<String> itValues = values.iterator();
while (itValues.hasNext()) {
string = string.concat(itValues.next());
if (itValues.hasNext()) {
string = string.concat(";");
}
}
for (Entry<String, String> directive : directives.entrySet()) {
string = string.concat(";");
string = string.concat(directive.getKey());
string = string.concat(":=");
string = string.concat(directive.getValue());
}
for (Entry<String, String> attribute : attributes.entrySet()) {
string = string.concat(";");
string = string.concat(attribute.getKey());
string = string.concat("=");
string = string.concat(attribute.getValue());
}
return string;
}
}

View File

@ -0,0 +1,425 @@
/*
* 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.ivy.osgi.core;
import java.io.PrintStream;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
/**
* Parse a header of a manifest. The manifest header is composed with the following rules:
*
* <pre>
* header ::= header-element (',' header-element)*
* header-element ::= values (';' (attribute | directive) )*
* values ::= value (';' value)*
* value ::= &lt;any string value that does not have ';' or ','&gt;
* attribute ::= key '=' value
* directive ::= key '=' value
* key ::= token
* value ::= token | quoted-string | double-quoted-string
* </pre>
*/
public class ManifestHeaderValue {
private List<ManifestHeaderElement> elements = new ArrayList<ManifestHeaderElement>();
ManifestHeaderValue() {
// just for unit testing
}
public ManifestHeaderValue(String header) throws ParseException {
if (header != null) {
new ManifestHeaderParser(header).parse();
}
}
public List<ManifestHeaderElement> getElements() {
return elements;
}
public String getSingleValue() {
if (elements.isEmpty()) {
return null;
}
List<String> values = getElements().iterator().next().getValues();
if (values.isEmpty()) {
return null;
}
return values.iterator().next();
}
public List<String> getValues() {
if (elements.isEmpty()) {
return Collections.emptyList();
}
List<String> list = new ArrayList<String>();
for (ManifestHeaderElement element : getElements()) {
list.addAll(element.getValues());
}
return list;
}
void addElement(ManifestHeaderElement element) {
this.elements.add(element);
}
class ManifestHeaderParser {
/**
* header to parse
*/
private final String header;
/**
* the length of the source
*/
private int length;
/**
* buffer
*/
private StringBuilder buffer = new StringBuilder();
/**
* position in the source
*/
private int pos = 0;
/**
* last read character
*/
private char c;
/**
* the header element being build
*/
private ManifestHeaderElement elem = new ManifestHeaderElement();
/**
* Once at true (at the first attribute parsed), only parameters are allowed
*/
private boolean valuesParsed;
/**
* the last parsed parameter name
*/
private String paramName;
/**
* true if the last parsed parameter is a directive (assigned via :=)
*/
private boolean isDirective;
/**
* Default constructor
*
* @param header
* the header to parse
*/
ManifestHeaderParser(String header) {
this.header = header;
this.length = header.length();
}
/**
* Do the parsing
*
* @throws ParseException
*/
void parse() throws ParseException {
do {
elem = new ManifestHeaderElement();
int posElement = pos;
parseElement();
if (elem.getValues().isEmpty()) {
error("No defined value", posElement);
// try to recover: ignore that element
continue;
}
addElement(elem);
} while (pos < length);
}
private char readNext() {
if (pos == length) {
c = '\0';
} else {
c = header.charAt(pos++);
}
return c;
}
private void error(String message) throws ParseException {
error(message, pos - 1);
}
private void error(String message, int p) throws ParseException {
throw new ParseException(message, p);
}
private void parseElement() throws ParseException {
valuesParsed = false;
do {
parseValueOrParameter();
} while (c == ';' && pos < length);
}
private void parseValueOrParameter() throws ParseException {
// true if the value/parameter parsing has started, white spaces skipped
boolean start = false;
// true if the value/parameter parsing is ended, then only white spaces are allowed
boolean end = false;
do {
switch (readNext()) {
case '\0':
break;
case ';':
case ',':
endValue();
return;
case ':':
case '=':
endParameterName();
parseSeparator();
parseParameterValue();
return;
case ' ':
case '\t':
case '\n':
case '\r':
if (start) {
end = true;
}
break;
default:
if (end) {
error("Expecting the end of a value or of an parameter name");
// try to recover: restart the parsing of the value or parameter
end = false;
}
start = true;
buffer.append(c);
}
} while (pos < length);
endValue();
}
private void endValue() throws ParseException {
if (valuesParsed) {
error("Early end of a parameter");
// try to recover: ignore it
buffer.setLength(0);
return;
}
if (buffer.length() == 0) {
error("Empty value");
// try to recover: just ignore the error
}
elem.addValue(buffer.toString());
buffer.setLength(0);
}
private void endParameterName() throws ParseException {
if (buffer.length() == 0) {
error("Empty parameter name");
// try to recover: won't store the value
paramName = null;
}
paramName = buffer.toString();
buffer.setLength(0);
}
private void parseSeparator() throws ParseException {
if (c == '=') {
isDirective = false;
return;
}
if (readNext() != '=') {
error("Expecting '='");
// try to recover: will ignore this parameter
pos--;
paramName = null;
}
isDirective = true;
}
private void parseParameterValue() throws ParseException {
// true if the value parsing has started, white spaces skipped
boolean start = false;
// true if the value parsing is ended, then only white spaces are allowed
boolean end = false;
boolean doubleQuoted = false;
do {
switch (readNext()) {
case '\0':
break;
case ',':
case ';':
endParameterValue();
return;
case '=':
case ':':
error("Illegal character '" + c + "' in parameter value of " + paramName);
// try to recover: ignore that parameter
paramName = null;
break;
case '\"':
doubleQuoted = true;
case '\'':
if (end && paramName != null) {
error("Expecting the end of a parameter value");
// try to recover: ignore that parameter
paramName = null;
}
if (start) {
// quote in the middle of the value, just add it as a quote
buffer.append(c);
} else {
start = true;
appendQuoted(doubleQuoted);
end = true;
}
break;
case '\\':
if (end && paramName != null) {
error("Expecting the end of a parameter value");
// try to recover: ignore that parameter
paramName = null;
}
start = true;
appendEscaped();
break;
case ' ':
case '\t':
case '\n':
case '\r':
if (start) {
end = true;
}
break;
default:
if (end && paramName != null) {
error("Expecting the end of a parameter value");
// try to recover: ignore that parameter
paramName = null;
}
start = true;
buffer.append(c);
}
} while (pos < length);
endParameterValue();
}
private void endParameterValue() throws ParseException {
if (paramName == null) {
// recovering from an incorrect parameter: skip the value
return;
}
if (buffer.length() == 0) {
error("Empty parameter value");
// try to recover: do not store the parameter
return;
}
String value = buffer.toString();
if (isDirective) {
elem.addDirective(paramName, value);
} else {
elem.addAttribute(paramName, value);
}
valuesParsed = true;
buffer.setLength(0);
}
private void appendQuoted(boolean doubleQuoted) {
do {
switch (readNext()) {
case '\0':
break;
case '\"':
if (doubleQuoted) {
return;
}
buffer.append(c);
break;
case '\'':
if (!doubleQuoted) {
return;
}
buffer.append(c);
break;
case '\\':
break;
default:
buffer.append(c);
}
} while (pos < length);
}
private void appendEscaped() {
if (pos < length) {
buffer.append(readNext());
} else {
buffer.append(c);
}
}
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ManifestHeaderValue)) {
return false;
}
ManifestHeaderValue other = (ManifestHeaderValue) obj;
if (other.elements.size() != elements.size()) {
return false;
}
for (ManifestHeaderElement element : elements) {
if (!other.elements.contains(element)) {
return false;
}
}
return true;
}
@Override
public String toString() {
String string = "";
Iterator<ManifestHeaderElement> it = elements.iterator();
while (it.hasNext()) {
string = string.concat(it.next().toString());
if (it.hasNext()) {
string = string.concat(",");
}
}
return string;
}
public static void writeParseException(PrintStream out, String source, ParseException e) {
out.println(e.getMessage());
out.print(" " + source + "\n ");
for (int i = 0; i < e.getErrorOffset(); i++) {
out.print(' ');
}
out.println('^');
}
}

View File

@ -0,0 +1,201 @@
/*
* 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.ivy.osgi.core;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.util.List;
import java.util.jar.Attributes;
import java.util.jar.JarInputStream;
import java.util.jar.Manifest;
import org.apache.ivy.osgi.util.Version;
import org.apache.ivy.osgi.util.VersionRange;
/**
* Provides an OSGi manifest parser.
*
*/
public class ManifestParser {
private static final String EXPORT_PACKAGE = "Export-Package";
private static final String IMPORT_PACKAGE = "Import-Package";
private static final String EXPORT_SERVICE = "Export-Service";
private static final String IMPORT_SERVICE = "Import-Service";
private static final String REQUIRE_BUNDLE = "Require-Bundle";
private static final String BUNDLE_VERSION = "Bundle-Version";
private static final String BUNDLE_NAME = "Bundle-Name";
private static final String BUNDLE_DESCRIPTION = "Bundle-Description";
private static final String BUNDLE_SYMBOLIC_NAME = "Bundle-SymbolicName";
private static final String BUNDLE_MANIFEST_VERSION = "Bundle-ManifestVersion";
private static final String BUNDLE_REQUIRED_EXECUTION_ENVIRONMENT = "Bundle-RequiredExecutionEnvironment";
private static final String ATTR_RESOLUTION = "resolution";
private static final String ATTR_VERSION = "version";
private static final String ATTR_BUNDLE_VERSION = "bundle-version";
private static final String ATTR_USE = "use";
public static BundleInfo parseJarManifest(InputStream jarStream) throws IOException, ParseException {
final JarInputStream jis = new JarInputStream(jarStream);
final BundleInfo parseManifest = parseManifest(jis.getManifest());
jis.close();
return parseManifest;
}
public static BundleInfo parseManifest(File manifestFile) throws IOException, ParseException {
final FileInputStream fis = new FileInputStream(manifestFile);
final BundleInfo parseManifest = parseManifest(fis);
fis.close();
return parseManifest;
}
public static BundleInfo parseManifest(InputStream manifestStream) throws IOException, ParseException {
final BundleInfo parseManifest = parseManifest(new Manifest(manifestStream));
manifestStream.close();
return parseManifest;
}
public static BundleInfo parseManifest(Manifest manifest) throws ParseException {
Attributes mainAttributes = manifest.getMainAttributes();
String manifestVersion = mainAttributes.getValue(BUNDLE_MANIFEST_VERSION);
if (manifestVersion == null) {
// non OSGi manifest
throw new ParseException("No " + BUNDLE_MANIFEST_VERSION + " in the manifest", 0);
}
String symbolicName = new ManifestHeaderValue(mainAttributes.getValue(BUNDLE_SYMBOLIC_NAME)).getSingleValue();
if (symbolicName == null) {
throw new ParseException("No " + BUNDLE_SYMBOLIC_NAME + " in the manifest", 0);
}
String description = new ManifestHeaderValue(mainAttributes.getValue(BUNDLE_DESCRIPTION)).getSingleValue();
if (description == null) {
description = new ManifestHeaderValue(mainAttributes.getValue(BUNDLE_DESCRIPTION)).getSingleValue();
}
String vBundle = new ManifestHeaderValue(mainAttributes.getValue(BUNDLE_VERSION)).getSingleValue();
Version version;
try {
version = versionOf(vBundle);
} catch (NumberFormatException e) {
throw new ParseException("The " + BUNDLE_VERSION + " has an incorrect version: " + vBundle + " ("
+ e.getMessage() + ")", 0);
}
BundleInfo bundleInfo = new BundleInfo(symbolicName, version);
bundleInfo.setDescription(description);
List<String> environments = new ManifestHeaderValue(mainAttributes
.getValue(BUNDLE_REQUIRED_EXECUTION_ENVIRONMENT)).getValues();
bundleInfo.setExecutionEnvironments(environments);
parseRequirement(bundleInfo, mainAttributes, REQUIRE_BUNDLE, BundleInfo.BUNDLE_TYPE, ATTR_BUNDLE_VERSION);
parseRequirement(bundleInfo, mainAttributes, IMPORT_PACKAGE, BundleInfo.PACKAGE_TYPE, ATTR_VERSION);
parseRequirement(bundleInfo, mainAttributes, IMPORT_SERVICE, BundleInfo.SERVICE_TYPE, ATTR_VERSION);
ManifestHeaderValue exportElements = new ManifestHeaderValue(mainAttributes.getValue(EXPORT_PACKAGE));
for (ManifestHeaderElement exportElement : exportElements.getElements()) {
String vExport = exportElement.getAttributes().get(ATTR_VERSION);
Version v = null;
try {
v = versionOf(vExport);
} catch (NumberFormatException e) {
throw new ParseException("The " + EXPORT_PACKAGE + " has an incorrect version: " + vExport + " ("
+ e.getMessage() + ")", 0);
}
for (String name : exportElement.getValues()) {
ExportPackage export = new ExportPackage(name, v);
String uses = exportElement.getDirectives().get(ATTR_USE);
if (uses != null) {
String[] split = uses.trim().split(",");
for (String u : split) {
export.addUse(u.trim());
}
}
bundleInfo.addCapability(export);
}
}
parseCapability(bundleInfo, mainAttributes, EXPORT_SERVICE, BundleInfo.SERVICE_TYPE);
return bundleInfo;
}
private static void parseRequirement(BundleInfo bundleInfo, Attributes mainAttributes, String headerName,
String type, String versionAttr) throws ParseException {
ManifestHeaderValue elements = new ManifestHeaderValue(mainAttributes.getValue(headerName));
for (ManifestHeaderElement element : elements.getElements()) {
String resolution = element.getDirectives().get(ATTR_RESOLUTION);
String attVersion = element.getAttributes().get(versionAttr);
VersionRange version = null;
try {
version = versionRangeOf(attVersion);
} catch (ParseException e) {
throw new ParseException("The " + headerName + " has an incorrect version: " + attVersion + " ("
+ e.getMessage() + ")", 0);
}
for (String name : element.getValues()) {
bundleInfo.addRequirement(new BundleRequirement(type, name, version, resolution));
}
}
}
private static void parseCapability(BundleInfo bundleInfo, Attributes mainAttributes, String headerName, String type)
throws ParseException {
ManifestHeaderValue elements = new ManifestHeaderValue(mainAttributes.getValue(headerName));
for (ManifestHeaderElement element : elements.getElements()) {
String attVersion = element.getAttributes().get(ATTR_VERSION);
Version version = null;
try {
version = versionOf(attVersion);
} catch (NumberFormatException e) {
throw new ParseException("The " + headerName + " has an incorrect version: " + attVersion + " ("
+ e.getMessage() + ")", 0);
}
for (String name : element.getValues()) {
BundleCapability export = new BundleCapability(type, name, version);
bundleInfo.addCapability(export);
}
}
}
private static VersionRange versionRangeOf(String v) throws ParseException {
if (v == null) {
return null;
}
return new VersionRange(v);
}
private static Version versionOf(String v) throws NumberFormatException {
if (v == null) {
return null;
}
return new Version(v);
}
}

View File

@ -0,0 +1,146 @@
/*
* 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.ivy.osgi.ivy;
import static java.lang.String.format;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import org.apache.ivy.core.module.descriptor.Artifact;
import org.apache.ivy.core.module.descriptor.DefaultArtifact;
import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.core.resolve.ResolveData;
import org.apache.ivy.osgi.ivy.internal.FilePackageScanner;
import org.apache.ivy.osgi.ivy.internal.JarEntryResource;
import org.apache.ivy.osgi.ivy.internal.JarFileRepository;
import org.apache.ivy.osgi.util.ZipUtil;
import org.apache.ivy.plugins.repository.Resource;
import org.apache.ivy.plugins.repository.file.FileRepository;
import org.apache.ivy.plugins.repository.file.FileResource;
import org.apache.ivy.plugins.resolver.FileSystemResolver;
import org.apache.ivy.plugins.resolver.util.ResolvedResource;
import org.apache.ivy.util.Message;
/**
* An OSGi file system resolver.
*
* @author alex@radeski.net
*/
public class OsgiFileResolver extends FileSystemResolver {
private final FilePackageScanner packageScanner = new FilePackageScanner();
public OsgiFileResolver() {
setRepository(new JarFileRepository());
}
@Override
protected ResolvedResource findArtifactRef(Artifact artifact, Date date) {
Message.debug(format("\tfind artifact ref: artifact=%s, date=%s", artifact, date));
final ModuleRevisionId newMrid = artifact.getModuleRevisionId();
ResolvedResource resolvedResource = findResourceUsingPatterns(newMrid,
getArtifactPatterns(),
artifact,
getDefaultRMDParser(artifact.getModuleRevisionId().getModuleId()),
date);
Message.debug(format("\t\tfind artifact ref: mrid=%s, resource=%s", newMrid, resolvedResource));
if (resolvedResource == null) {
Message.debug("\t\tfind artifact file ref: resource was null");
return null;
}
final Resource resource = resolvedResource.getResource();
if ((resource instanceof FileResource) && ((FileResource) resource).getFile().isDirectory()) {
FileResource dirResource = (FileResource) resource;
try {
final File bundleZipFile = File.createTempFile("ivy-osgi-" + newMrid, ".zip");
ZipUtil.zip(dirResource.getFile(), new FileOutputStream(bundleZipFile));
Message.debug("\t\tfind artifact ref: zip file=" + bundleZipFile);
return new ResolvedResource(new FileResource(dirResource.getRepository(), bundleZipFile), resolvedResource.getRevision());
} catch (IOException e) {
throw new IllegalStateException("Failed to create temp zip file for bundle:" + newMrid);
}
}
Message.debug("\t\tfind artifact ref: resource=" + resolvedResource);
return resolvedResource;
}
@SuppressWarnings("unchecked")
@Override
public ResolvedResource findIvyFileRef(DependencyDescriptor dd, ResolveData data) {
packageScanner.scanAllPackageExportHeaders(getIvyPatterns(), getSettings());
Message.debug(format("\tfind ivy file ref: dd=%s, data=%s", dd, data));
final ModuleRevisionId newMrid = dd.getDependencyRevisionId();
final ResolvedResource bundleResolvedResource = findResourceUsingPatterns(newMrid,
getIvyPatterns(),
DefaultArtifact.newIvyArtifact(newMrid, data.getDate()),
getRMDParser(dd, data),
data.getDate());
if (bundleResolvedResource == null) {
Message.debug("\tfind ivy file ref: resource was null");
return null;
}
final Resource bundleResource = bundleResolvedResource.getResource();
Resource res = null;
if ((bundleResource instanceof FileResource) && ((FileResource) bundleResource).getFile().isDirectory()) {
final FileResource fileResource = (FileResource) bundleResource;
res = new FileResource((FileRepository) getRepository(), new File(fileResource.getFile(), "META-INF/MANIFEST.MF"));
} else if (bundleResource.getName().toUpperCase().endsWith(".JAR")) {
res = new JarEntryResource(bundleResource, "META-INF/MANIFEST.MF");
}
ResolvedResource resolvedResource = new ResolvedResource(res, bundleResolvedResource.getRevision());
Message.debug(format("\tfind ivy file ref: resource=%s", bundleResolvedResource));
return resolvedResource;
}
// protected ModuleRevisionId modifyModuleRevisionId(final ModuleRevisionId oldMrid) {
// String revision = oldMrid.getRevision();
// try {
// VersionRange versionRange = new VersionRange(oldMrid.getRevision());
// revision = versionRange.toIvyRevision();
// } catch (ParseException nfe) {
// // Do nothing as we fallback to default behaviour
// }
// final ModuleRevisionId newMrid = ModuleRevisionId.newInstance(oldMrid.getOrganisation(),
// oldMrid.getName(),
// oldMrid.getBranch(),
// revision,
// oldMrid.getExtraAttributes());
// return newMrid;
// }
}

View File

@ -0,0 +1,195 @@
/*
* 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.ivy.osgi.ivy;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.ParseException;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.ivy.core.module.descriptor.Artifact;
import org.apache.ivy.core.module.descriptor.Configuration;
import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor;
import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
import org.apache.ivy.core.module.descriptor.ExcludeRule;
import org.apache.ivy.core.module.descriptor.License;
import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.plugins.parser.ModuleDescriptorParser;
import org.apache.ivy.plugins.parser.ModuleDescriptorParserRegistry;
import org.apache.ivy.plugins.parser.ParserSettings;
import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorParser;
import org.apache.ivy.plugins.repository.url.URLResource;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
public class OsgiIvyParser extends XmlModuleDescriptorParser {
public static class OsgiParser extends Parser {
private ModuleDescriptor manifestMD = null;
public OsgiParser(ModuleDescriptorParser parser, ParserSettings ivySettings) {
super(parser, ivySettings);
}
@Override
protected void infoStarted(Attributes attributes) {
String manifest = attributes.getValue("manifest");
if (manifest != null) {
try {
manifestMD = parseManifest(manifest);
includeMdInfo(getMd(), manifestMD);
} catch (SAXException e) {
// it is caught in the startElement method
throw new RuntimeException(e);
}
return;
}
super.infoStarted(attributes);
}
public ModuleDescriptor parseManifest(String manifest) throws SAXException {
if (getDescriptorURL() == null) {
throw new SAXException(
"A reference to a manifest is only supported on module descriptors which are parsed from an URL");
}
URL includedUrl;
try {
includedUrl = getSettings().getRelativeUrlResolver().getURL(getDescriptorURL(), manifest);
} catch (MalformedURLException e) {
SAXException pe = new SAXException("Incorrect relative url of the include in '" + getDescriptorURL()
+ "' (" + e.getMessage() + ")");
pe.initCause(e);
throw pe;
}
URLResource includeResource = new URLResource(includedUrl);
ModuleDescriptorParser parser = ModuleDescriptorParserRegistry.getInstance().getParser(includeResource);
ModuleDescriptor manifestMd;
try {
manifestMd = parser.parseDescriptor(getSettings(), includeResource.getURL(), includeResource,
isValidate());
} catch (ParseException e) {
SAXException pe = new SAXException("Incorrect included md '" + includeResource + "' in '"
+ getDescriptorURL() + "' (" + e.getMessage() + ")");
pe.initCause(e);
throw pe;
} catch (IOException e) {
SAXException pe = new SAXException("Unreadable included md '" + includeResource + "' in '"
+ getDescriptorURL() + "' (" + e.getMessage() + ")");
pe.initCause(e);
throw pe;
}
return manifestMd;
}
@Override
public void endDocument() throws SAXException {
if (manifestMD != null) {
includeMdDepedencies(getMd(), manifestMD);
}
}
}
@Override
protected Parser newParser(ParserSettings ivySettings) {
return new OsgiParser(this, ivySettings);
}
private static void includeMdInfo(DefaultModuleDescriptor md, ModuleDescriptor include) {
ModuleRevisionId mrid = include.getModuleRevisionId();
if (mrid != null) {
md.setModuleRevisionId(mrid);
}
ModuleRevisionId resolvedMrid = include.getResolvedModuleRevisionId();
if (resolvedMrid != null) {
md.setResolvedModuleRevisionId(resolvedMrid);
}
String description = include.getDescription();
if (description != null) {
md.setDescription(description);
}
String homePage = include.getHomePage();
if (homePage != null) {
md.setHomePage(homePage);
}
long lastModified = include.getLastModified();
if (lastModified > md.getLastModified()) {
md.setLastModified(lastModified);
}
String status = include.getStatus();
if (status != null) {
md.setStatus(status);
}
Map<String, String> extraInfo = include.getExtraInfo();
if (extraInfo != null) {
for (Entry<String, String> info : extraInfo.entrySet()) {
md.addExtraInfo(info.getKey(), info.getValue());
}
}
License[] licenses = include.getLicenses();
if (licenses != null) {
for (int i = 0; i < licenses.length; i++) {
md.addLicense(licenses[i]);
}
}
Configuration[] configurations = include.getConfigurations();
if (configurations != null) {
for (int i = 0; i < configurations.length; i++) {
md.addConfiguration(configurations[i]);
}
}
}
private static void includeMdDepedencies(DefaultModuleDescriptor md, ModuleDescriptor include) {
Artifact[] artifacts = include.getAllArtifacts();
if (artifacts != null) {
for (int i = 0; i < artifacts.length; i++) {
String[] artifactConfs = artifacts[i].getConfigurations();
for (int j = 0; j < artifactConfs.length; j++) {
md.addArtifact(artifactConfs[j], artifacts[i]);
}
}
}
DependencyDescriptor[] dependencies = include.getDependencies();
if (dependencies != null) {
for (int i = 0; i < dependencies.length; i++) {
md.addDependency(dependencies[i]);
}
}
ExcludeRule[] excludeRules = include.getAllExcludeRules();
if (excludeRules != null) {
for (int i = 0; i < excludeRules.length; i++) {
md.addExcludeRule(excludeRules[i]);
}
}
}
}

View File

@ -0,0 +1,249 @@
/*
* 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.ivy.osgi.ivy;
import static java.lang.String.format;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.text.ParseException;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.jar.JarInputStream;
import java.util.jar.Manifest;
import java.util.regex.Pattern;
import org.apache.ivy.core.module.descriptor.Configuration;
import org.apache.ivy.core.module.descriptor.DefaultArtifact;
import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor;
import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor;
import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.osgi.core.BundleInfo;
import org.apache.ivy.osgi.core.BundleRequirement;
import org.apache.ivy.osgi.core.ExportPackage;
import org.apache.ivy.osgi.core.ManifestParser;
import org.apache.ivy.osgi.ivy.internal.PackageRegistry;
import org.apache.ivy.osgi.util.NameUtil;
import org.apache.ivy.osgi.util.NameUtil.OrgAndName;
import org.apache.ivy.plugins.parser.AbstractModuleDescriptorParser;
import org.apache.ivy.plugins.parser.ModuleDescriptorParser;
import org.apache.ivy.plugins.parser.ParserSettings;
import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorWriter;
import org.apache.ivy.plugins.repository.Resource;
import org.apache.ivy.util.Message;
import org.apache.tools.ant.types.resources.FileResource;
/**
* An parser for OSGi Manifest descriptor.
*
* @author jerome@benois.fr
* @author alex@radeski.net
*/
public class OsgiManifestParser extends AbstractModuleDescriptorParser {
public static final String PACKAGE = ".package";
protected static final Pattern PATH_REGEX = Pattern
.compile("(.*/)?([\\w\\.]+)[\\-_](\\d\\.\\d\\.\\d)[\\.]?([\\w]+)?");
private static final OsgiManifestParser INSTANCE = new OsgiManifestParser();
public static OsgiManifestParser getInstance() {
return INSTANCE;
}
public boolean accept(Resource res) {
if (res == null || res.getName() == null || res.getName().trim().equals("")) {
return false;
}
return res.getName().toUpperCase().endsWith("META-INF/MANIFEST.MF")
|| res.getName().toUpperCase().endsWith(".JAR") || res.getName().toUpperCase().endsWith(".PKGREF");
}
public ModuleDescriptor parseDescriptor(ParserSettings ivySettings, URL descriptorURL, Resource res,
boolean validate) throws ParseException, IOException {
Message.debug(format("\tparse descriptor: resource=%s", res));
final InternalParser parser = new InternalParser(this);
parser.parse(res, ivySettings);
return parser.getModuleDescriptor();
}
public ModuleDescriptor parseExports(Resource res) throws ParseException, IOException {
Message.debug(format("\tparse descriptor: resource=%s", res));
final InternalParser parser = new InternalParser(this);
parser.parse(res, true);
return parser.getModuleDescriptor();
}
public void toIvyFile(InputStream is, Resource res, File destFile, ModuleDescriptor md) throws ParseException,
IOException {
try {
XmlModuleDescriptorWriter.write(md, destFile);
} finally {
if (is != null) {
is.close();
}
}
}
public static class InternalParser extends AbstractParser {
protected InternalParser(ModuleDescriptorParser parser) {
super(parser);
}
public void parse(Resource res, ParserSettings ivySettings) throws IOException {
parse(res, false);
}
public void parse(Resource res, boolean useExports) throws IOException {
Manifest manifest;
if ((res instanceof FileResource) && ((FileResource) res).isDirectory()) {
manifest = new Manifest(new FileInputStream(res.getName() + "/META-INF/MANIFEST.MF"));
} else if (res.getName().toUpperCase().endsWith(".JAR")) {
manifest = new JarInputStream(res.openStream()).getManifest();
} else {
manifest = new Manifest(res.openStream());
}
if (manifest == null) {
return;
}
BundleInfo info;
try {
info = ManifestParser.parseManifest(manifest);
} catch (ParseException e) {
IOException ioe = new IOException();
ioe.initCause(e);
throw ioe;
}
setResource(res);
// Set Info
OrgAndName orgAndName = NameUtil.instance().asOrgAndName(info.getSymbolicName());
final ModuleRevisionId mrid = ModuleRevisionId.newInstance(orgAndName.org, orgAndName.name, info
.getVersion().toString());
getMd().setDescription(info.getDescription());
getMd().setResolvedPublicationDate(new Date(res.getLastModified()));
getMd().setModuleRevisionId(mrid);
getMd().addConfiguration(new Configuration("default"));
getMd().addConfiguration(new Configuration("optional"));
getMd().addConfiguration(new Configuration("source"));
getMd().setStatus("release");
getMd().addArtifact("default",
new DefaultArtifact(mrid, getDefaultPubDate(), info.getSymbolicName(), "jar", "jar"));
getMd().addArtifact("source",
new DefaultArtifact(mrid, getDefaultPubDate(), info.getSymbolicName() + ".source", "src", "jar"));
if (useExports) {
addExports(getMd(), info.getExports());
} else {
Set<ModuleRevisionId> processedDeps = new HashSet<ModuleRevisionId>();
processedDeps.add(mrid);
addRequiredBundles(getMd(), info.getRequires(), processedDeps);
addImports(getMd(), info.getImports(), processedDeps);
}
Message.debug(format("\t\tparse: bundle info: %s", info.toString()));
}
protected void addExports(DefaultModuleDescriptor parent, Set<ExportPackage> bundleDependencies) {
for (final ExportPackage dep : bundleDependencies) {
String rev = "";
if (dep.getVersion() != null) {
rev = dep.getVersion().toString();
}
final ModuleRevisionId depMrid = ModuleRevisionId.newInstance(PACKAGE, dep.getName(), rev);
final DefaultDependencyDescriptor dd = new DefaultDependencyDescriptor(parent, depMrid, false, false,
true);
dd.addDependencyConfiguration("default", "default");
parent.addDependency(dd);
}
}
protected void addRequiredBundles(DefaultModuleDescriptor parent, Set<BundleRequirement> bundleDependencies,
Set<ModuleRevisionId> processedDeps) {
for (final BundleRequirement dep : bundleDependencies) {
String rev = "";
if (dep.getVersion() != null) {
rev = dep.getVersion().toIvyRevision();
}
OrgAndName orgAndName = NameUtil.instance().asOrgAndName(dep.getName());
final ModuleRevisionId depMrid = ModuleRevisionId.newInstance(orgAndName.org, orgAndName.name, rev);
if (processedDeps.contains(depMrid)) {
return;
}
processedDeps.add(depMrid);
final DefaultDependencyDescriptor dd = new DefaultDependencyDescriptor(parent, depMrid, false, false,
true);
if (dep.getResolution() == null) {
dd.addDependencyConfiguration("default", "default");
} else {
dd.addDependencyConfiguration(dep.getResolution(), dep.getResolution());
}
parent.addDependency(dd);
}
}
protected void addImports(DefaultModuleDescriptor parent, Set<BundleRequirement> bundleDependencies,
Set<ModuleRevisionId> processedDeps) {
for (final BundleRequirement dep : bundleDependencies) {
final ModuleRevisionId pkgMrid = PackageRegistry.getInstance().processImports(dep.getName(), dep.getVersion());
if (processedDeps.contains(pkgMrid)) {
return;
}
processedDeps.add(pkgMrid);
if (pkgMrid != null) {
final DefaultDependencyDescriptor dd = new DefaultDependencyDescriptor(parent, pkgMrid, false,
false, true);
if (dep.getResolution() == null) {
dd.addDependencyConfiguration("default", "default");
} else {
dd.addDependencyConfiguration(dep.getResolution(), dep.getResolution());
}
parent.addDependency(dd);
} else {
Message.error("Failed to resolve imported package: " + dep);
}
}
}
}
}

View File

@ -0,0 +1,223 @@
/*
* 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.ivy.osgi.ivy;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Pattern;
import org.apache.ivy.core.IvyContext;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.plugins.latest.ArtifactInfo;
import org.apache.ivy.plugins.latest.ComparatorLatestStrategy;
import org.apache.ivy.plugins.version.VersionMatcher;
public class OsgiRevisionStrategy extends ComparatorLatestStrategy {
private static final Pattern ALPHA_NUM_REGEX = Pattern.compile("([a-zA-Z])(\\d)");
private static final Pattern NUM_ALPHA_REGEX = Pattern.compile("(\\d)([a-zA-Z])");
private static final Pattern LABEL_REGEX = Pattern.compile("[_\\-\\+]");
/**
* Compares two ModuleRevisionId by their revision. Revisions are compared using an algorithm inspired by PHP
* version_compare one.
*/
final class MridComparator implements Comparator<ModuleRevisionId> {
public int compare(ModuleRevisionId o1, ModuleRevisionId o2) {
String rev1 = o1.getRevision();
String rev2 = o2.getRevision();
String[] outerParts1 = rev1.split("[\\.]");
String[] outerParts2 = rev2.split("[\\.]");
for (int i = 0; i < outerParts1.length && i < outerParts2.length; i++) {
String outerPart1 = outerParts1[i];
String outerPart2 = outerParts2[i];
if (outerPart1.equals(outerPart2)) {
continue;
}
outerPart1 = ALPHA_NUM_REGEX.matcher(outerPart1).replaceAll("$1_$2");
outerPart1 = NUM_ALPHA_REGEX.matcher(outerPart1).replaceAll("$1_$2");
outerPart2 = ALPHA_NUM_REGEX.matcher(outerPart2).replaceAll("$1_$2");
outerPart2 = NUM_ALPHA_REGEX.matcher(outerPart2).replaceAll("$1_$2");
String[] innerParts1 = LABEL_REGEX.split(outerPart1);
String[] innerParts2 = LABEL_REGEX.split(outerPart2);
for (int j = 0; j < innerParts1.length && j < innerParts2.length; j++) {
if (innerParts1[j].equals(innerParts2[j])) {
continue;
}
boolean is1Number = isNumber(innerParts1[j]);
boolean is2Number = isNumber(innerParts2[j]);
if (is1Number && !is2Number) {
return 1;
}
if (is2Number && !is1Number) {
return -1;
}
if (is1Number && is2Number) {
return Long.valueOf(innerParts1[j]).compareTo(Long.valueOf(innerParts2[j]));
}
// both are strings, we compare them taking into account special meaning
Map<String, Integer> meanings = getSpecialMeanings();
Integer sm1 = meanings.get(innerParts1[j].toLowerCase(Locale.US));
Integer sm2 = meanings.get(innerParts2[j].toLowerCase(Locale.US));
if (sm1 != null) {
sm2 = sm2 == null ? new Integer(0) : sm2;
return sm1.compareTo(sm2);
}
if (sm2 != null) {
return new Integer(0).compareTo(sm2);
}
return innerParts1[j].compareTo(innerParts2[j]);
}
if (i < innerParts1.length) {
return isNumber(innerParts1[i]) ? 1 : -1;
}
if (i < innerParts2.length) {
return isNumber(innerParts2[i]) ? -1 : 1;
}
}
if (outerParts1.length > outerParts2.length) {
return 1;
} else if (outerParts1.length < outerParts2.length) {
return -1;
}
return 0;
}
private boolean isNumber(String str) {
return str.matches("\\d+");
}
}
/**
* Compares two ArtifactInfo by their revision. Revisions are compared using an algorithm inspired by PHP
* version_compare one, unless a dynamic revision is given, in which case the version matcher is used to perform the
* comparison.
*/
final class ArtifactInfoComparator implements Comparator<ArtifactInfo> {
public int compare(ArtifactInfo o1, ArtifactInfo o2) {
String rev1 = o1.getRevision();
String rev2 = o2.getRevision();
/*
* The revisions can still be not resolved, so we use the current version matcher to know if one revision is
* dynamic, and in this case if it should be considered greater or lower than the other one. Note that if
* the version matcher compare method returns 0, it's because it's not possible to know which revision is
* greater. In this case we consider the dynamic one to be greater, because most of the time it will then be
* actually resolved and a real comparison will occur.
*/
VersionMatcher vmatcher = IvyContext.getContext().getSettings().getVersionMatcher();
ModuleRevisionId mrid1 = ModuleRevisionId.newInstance("", "", rev1);
ModuleRevisionId mrid2 = ModuleRevisionId.newInstance("", "", rev2);
if (vmatcher.isDynamic(mrid1)) {
int c = vmatcher.compare(mrid1, mrid2, mridComparator);
return c >= 0 ? 1 : -1;
} else if (vmatcher.isDynamic(mrid2)) {
int c = vmatcher.compare(mrid2, mrid1, mridComparator);
return c >= 0 ? -1 : 1;
}
return mridComparator.compare(mrid1, mrid2);
}
}
public static class SpecialMeaning {
private String name;
private Integer value;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
public void validate() {
if (name == null) {
throw new IllegalStateException("a special meaning should have a name");
}
if (value == null) {
throw new IllegalStateException("a special meaning should have a value");
}
}
}
private static final Map<String, Integer> DEFAULT_SPECIAL_MEANINGS;
static {
DEFAULT_SPECIAL_MEANINGS = new HashMap<String, Integer>();
DEFAULT_SPECIAL_MEANINGS.put("dev", new Integer(-1));
DEFAULT_SPECIAL_MEANINGS.put("rc", new Integer(1));
DEFAULT_SPECIAL_MEANINGS.put("final", new Integer(2));
}
private final Comparator<ModuleRevisionId> mridComparator = new MridComparator();
private final Comparator<ArtifactInfo> artifactInfoComparator = new ArtifactInfoComparator();
private Map<String, Integer> specialMeanings = null;
private boolean usedefaultspecialmeanings = true;
public OsgiRevisionStrategy() {
setComparator(artifactInfoComparator);
setName("latest-revision");
}
public void addConfiguredSpecialMeaning(SpecialMeaning meaning) {
meaning.validate();
getSpecialMeanings().put(meaning.getName().toLowerCase(Locale.US), meaning.getValue());
}
public synchronized Map<String, Integer> getSpecialMeanings() {
if (specialMeanings == null) {
specialMeanings = new HashMap<String, Integer>();
if (isUsedefaultspecialmeanings()) {
specialMeanings.putAll(DEFAULT_SPECIAL_MEANINGS);
}
}
return specialMeanings;
}
public boolean isUsedefaultspecialmeanings() {
return usedefaultspecialmeanings;
}
public void setUsedefaultspecialmeanings(boolean usedefaultspecialmeanings) {
this.usedefaultspecialmeanings = usedefaultspecialmeanings;
}
}

View File

@ -0,0 +1,86 @@
/*
* 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.ivy.osgi.ivy.internal;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.ivy.core.cache.DefaultRepositoryCacheManager;
import org.apache.ivy.plugins.repository.file.FileResource;
import org.apache.ivy.plugins.resolver.ResolverSettings;
import org.apache.ivy.util.Message;
public class FilePackageScanner {
private final Map<String, Collection<File>> patternFiles = new HashMap<String, Collection<File>>();
private final boolean useFileCache = false;
public void scanAllPackageExportHeaders(List<String> ivyPatterns, ResolverSettings settings) {
final DefaultRepositoryCacheManager cacheManager = (DefaultRepositoryCacheManager) settings.getDefaultRepositoryCacheManager();
for (String ivyPattern : ivyPatterns) {
Collection<File> fileList = null;
if ((fileList = patternFiles.get(ivyPattern)) == null || !useFileCache) {
patternFiles.put(ivyPattern, (fileList = new ArrayList<File>()));
final File rootDir = new File(ivyPattern.split("\\[[\\w]+\\]")[0]);
scanDir(rootDir, fileList);
}
for (File currFile : fileList) {
try {
PackageRegistry.getInstance().processExports(cacheManager.getBasedir(), new FileResource(null, currFile));
} catch (IOException e) {
Message.error("Failed to process exports for file: " + currFile);
}
}
}
}
protected void scanDir(File currFile, Collection<File> fileList) {
if (!currFile.canRead()) {
return;
}
if (currFile.isDirectory()) {
List<File> files = new ArrayList<File>();
for (File file : currFile.listFiles()) {
files.add(file);
//pre-process to check if we have recursed into an exploded bundle
if(file.getPath().endsWith("META-INF")) {
fileList.add(new File(file, "MANIFEST.MF"));
return;
}
}
//continue scanning...
for(File file : files) {
scanDir(file, fileList);
}
} else if (currFile.isFile()) {
final String path = currFile.getPath();
if (path.toUpperCase().endsWith("META-INF/MANIFEST.MF") || path.toUpperCase().endsWith(".JAR")) {
fileList.add(currFile);
}
}
}
}

View File

@ -0,0 +1,96 @@
/*
* 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.ivy.osgi.ivy.internal;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.apache.ivy.plugins.repository.Resource;
import org.apache.ivy.plugins.repository.file.FileRepository;
import org.apache.ivy.plugins.repository.file.FileResource;
/**
* A resource decorator that handles extracting jar file entries using the bang(!) notation to separate the internal
* entry name.
*
* @author alex@radeski.net
*/
public class JarEntryResource implements Resource {
private final String entryName;
private final Resource resource;
public JarEntryResource(String name) {
final String[] tokens = name.split("[!]");
final String path = tokens[0];
resource = new FileResource(new FileRepository(), new File(path));
entryName = tokens[1];
}
public JarEntryResource(Resource resource, String entryName) {
this.resource = resource;
this.entryName = entryName;
}
@Override
public String toString() {
return "resource:" + resource + ", jarEntry=" + entryName;
}
public Resource clone(String cloneName) {
return resource.clone(cloneName);
}
public boolean exists() {
return resource.exists();
}
public long getContentLength() {
return resource.getContentLength();
}
public long getLastModified() {
return resource.getLastModified();
}
public String getName() {
return resource.getName() + "!" + entryName;
}
public boolean isLocal() {
return resource.isLocal();
}
public InputStream openStream() throws IOException {
final ZipInputStream zis = new ZipInputStream(resource.openStream());
ZipEntry entry = null;
while ((entry = zis.getNextEntry()) != null) {
if (entry.getName().equalsIgnoreCase(entryName)) {
break;
}
}
if (entry == null) {
throw new IllegalStateException("Jar entry: " + entryName + ", not in resource:" + resource);
}
return zis;
}
}

View File

@ -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.ivy.osgi.ivy.internal;
import java.io.File;
import java.io.IOException;
import org.apache.ivy.plugins.repository.Resource;
import org.apache.ivy.plugins.repository.file.FileRepository;
/**
* A file repository that handles extracting jar file entries using the bang(!) notation to separate the internal
* entry name.
*
* @author alex@radeski.net
*/
public class JarFileRepository extends FileRepository {
private final RepositoryJarHandler jarHandler = new RepositoryJarHandler();
@Override
public void get(String source, File destination) throws IOException {
if(jarHandler.canHandle(source)) {
this.jarHandler.get(source, destination);
return;
}
super.get(source, destination);
}
@Override
public Resource getResource(String source) throws IOException {
if(jarHandler.canHandle(source)) {
return this.jarHandler.getResource(source);
}
return super.getResource(source);
}
}

View File

@ -0,0 +1,140 @@
/*
* 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.ivy.osgi.ivy.internal;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeMap;
import java.util.Map.Entry;
import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
import org.apache.ivy.core.module.id.ModuleId;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.osgi.ivy.OsgiManifestParser;
import org.apache.ivy.osgi.util.Version;
import org.apache.ivy.osgi.util.VersionComparator;
import org.apache.ivy.osgi.util.VersionRange;
import org.apache.ivy.plugins.repository.Resource;
import org.apache.ivy.util.Message;
import static org.apache.ivy.osgi.ivy.OsgiManifestParser.PACKAGE;
public class PackageRegistry {
private final static PackageRegistry instance = new PackageRegistry();
public static PackageRegistry getInstance() {
return instance;
}
private static final String PKGREF = ".pkgref";
private final OsgiManifestParser osgiManifestParser = new OsgiManifestParser();
private final Set<String> processedEntries = new HashSet<String>();
private File cacheDir;
private PackageRegistry() {
// nothing to initialize
}
public void processExports(File cacheDirectory, Resource res) throws IOException {
this.cacheDir = cacheDirectory;
if (processedEntries.contains(res.getName()) || !osgiManifestParser.accept(res)) {
return;
}
ModuleDescriptor md;
try {
md = osgiManifestParser.parseExports(res);
} catch (Exception e) {
Message.error("\t\tFailed to parse package resource descriptor: " + res);
e.printStackTrace();
return;
}
if(md == null) {
return;
}
final ModuleRevisionId mrid = md.getResolvedModuleRevisionId();
final File pkgRootDir = new File(cacheDir, PACKAGE);
pkgRootDir.mkdirs();
for (DependencyDescriptor dep : md.getDependencies()) {
final ModuleRevisionId depMrid = dep.getDependencyRevisionId();
if (depMrid.getOrganisation().equalsIgnoreCase(PACKAGE)) {
final File pkgDir = new File(pkgRootDir, (depMrid.getName().replace('.', '/') + "/"));
pkgDir.mkdirs();
final File file = new File(pkgDir, mrid + PKGREF);
if(!file.exists()) {
Message.debug("\t\tWriting pkg ref: " + file);
file.createNewFile();
}
}
}
processedEntries.add(res.getName());
}
public ModuleRevisionId processImports(final String pkgName, final VersionRange importRange) {
final File pkgRootDir = new File(cacheDir, PACKAGE);
if (!pkgRootDir.canRead() || !pkgRootDir.isDirectory()) {
return null;
}
final File pkgDir = new File(pkgRootDir, pkgName.replace('.', '/') + "/");
final TreeMap<Version, ModuleRevisionId> pkgMrids = new TreeMap<Version, ModuleRevisionId>(VersionComparator.DESCENDING);
pkgDir.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
if (name.endsWith(PKGREF)) {
final String baseName = name.substring(0, (name.length() - PKGREF.length()));
final int hashIdx = baseName.indexOf('#');
final int semicolIdx = baseName.indexOf(';');
final String mridOrg = baseName.substring(0, hashIdx);
final String[] tokens = baseName.substring(hashIdx + 1, semicolIdx).split("[#]");
final String mridName = tokens[0];
final String mridBranch = (tokens.length > 1 ? tokens[1] : null);
final String mridRev = baseName.substring(semicolIdx + 1);
pkgMrids.put(new Version(mridRev), new ModuleRevisionId(new ModuleId(mridOrg, mridName), mridBranch, mridRev));
}
return false;
}
});
ModuleRevisionId matchingMrid = null;
for (Entry<Version, ModuleRevisionId> entry : pkgMrids.entrySet()) {
if (importRange == null || importRange.contains(entry.getKey())) {
matchingMrid = entry.getValue();
break;
}
}
return matchingMrid;
}
}

View File

@ -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.ivy.osgi.ivy.internal;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ivy.plugins.repository.Resource;
import org.apache.ivy.util.FileUtil;
public class RepositoryJarHandler {
public boolean canHandle(String source) {
return source.toUpperCase().contains(".JAR!");
}
public void get(String source, File destination) throws IOException {
final InputStream inputStream = new JarEntryResource(source).openStream();
FileUtil.copy(inputStream, destination, null);
inputStream.close();
}
public Resource getResource(String source) {
return new JarEntryResource(source);
}
}

View File

@ -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.ivy.osgi.obr.filter;
import org.apache.ivy.osgi.obr.xml.RequirementFilter;
public class AndFilter extends MultiOperatorFilter {
public AndFilter() {
super();
}
public AndFilter(RequirementFilter... filters) {
super(filters);
}
@Override
protected char operator() {
return '&';
}
}

View File

@ -0,0 +1,126 @@
/*
* 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.ivy.osgi.obr.filter;
import org.apache.ivy.osgi.obr.xml.RequirementFilter;
public class CompareFilter extends RequirementFilter {
public enum Operator {
EQUALS, LOWER_THAN, LOWER_OR_EQUAL, GREATER_THAN, GREATER_OR_EQUAL;
@Override
public String toString() {
switch (this) {
case EQUALS:
return "=";
case GREATER_THAN:
return ">";
case GREATER_OR_EQUAL:
return ">=";
case LOWER_THAN:
return "<";
case LOWER_OR_EQUAL:
return "<=";
default:
break;
}
return super.toString();
}
}
private Operator operator;
private final String rightValue;
private final String leftValue;
public CompareFilter(String leftValue, Operator operator, String rightValue) {
this.leftValue = leftValue;
this.rightValue = rightValue;
this.operator = operator;
}
public String getLeftValue() {
return leftValue;
}
public Operator getOperator() {
return operator;
}
public String getRightValue() {
return rightValue;
}
@Override
public void append(StringBuilder builder) {
builder.append("(");
builder.append(leftValue);
builder.append(operator.toString());
builder.append(rightValue);
builder.append(")");
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((leftValue == null) ? 0 : leftValue.hashCode());
result = prime * result + ((operator == null) ? 0 : operator.hashCode());
result = prime * result + ((rightValue == null) ? 0 : rightValue.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof CompareFilter)) {
return false;
}
CompareFilter other = (CompareFilter) obj;
if (leftValue == null) {
if (other.leftValue != null) {
return false;
}
} else if (!leftValue.equals(other.leftValue)) {
return false;
}
if (operator == null) {
if (other.operator != null) {
return false;
}
} else if (!operator.equals(other.operator)) {
return false;
}
if (rightValue == null) {
if (other.rightValue != null) {
return false;
}
} else if (!rightValue.equals(other.rightValue)) {
return false;
}
return true;
}
}

View File

@ -0,0 +1,95 @@
/*
* 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.ivy.osgi.obr.filter;
import java.util.ArrayList;
import java.util.List;
import org.apache.ivy.osgi.obr.xml.RequirementFilter;
public abstract class MultiOperatorFilter extends RequirementFilter {
private List<RequirementFilter> subFilters = new ArrayList<RequirementFilter>();
public MultiOperatorFilter() {
// default constructor
}
public MultiOperatorFilter(RequirementFilter... filters) {
for (RequirementFilter filter : filters) {
add(filter);
}
}
abstract protected char operator();
@Override
public void append(StringBuilder builder) {
builder.append('(');
builder.append(operator());
for (RequirementFilter filter : subFilters) {
filter.append(builder);
}
builder.append(')');
}
public void add(RequirementFilter subFilter2) {
subFilters.add(subFilter2);
}
public List<RequirementFilter> getSubFilters() {
return subFilters;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
for (RequirementFilter subFilter : subFilters) {
result = prime * result + ((subFilter == null) ? 0 : subFilter.hashCode());
}
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof MultiOperatorFilter)) {
return false;
}
MultiOperatorFilter other = (MultiOperatorFilter) obj;
if (subFilters == null) {
if (other.subFilters != null) {
return false;
}
} else if (other.subFilters == null) {
return false;
} else if (subFilters.size() != other.subFilters.size()) {
return false;
} else if (!subFilters.containsAll(other.subFilters)) {
return false;
}
return true;
}
}

View File

@ -0,0 +1,32 @@
/*
* 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.ivy.osgi.obr.filter;
import org.apache.ivy.osgi.obr.xml.RequirementFilter;
public class NotFilter extends UniOperatorFilter {
public NotFilter(RequirementFilter subFilter) {
super(subFilter);
}
@Override
protected char operator() {
return '!';
}
}

View File

@ -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.ivy.osgi.obr.filter;
import org.apache.ivy.osgi.obr.xml.RequirementFilter;
public class OrFilter extends MultiOperatorFilter {
public OrFilter() {
super();
}
public OrFilter(RequirementFilter... filters) {
super(filters);
}
@Override
protected char operator() {
return '|';
}
}

View File

@ -0,0 +1,211 @@
/*
* 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.ivy.osgi.obr.filter;
import java.text.ParseException;
import org.apache.ivy.osgi.obr.filter.CompareFilter.Operator;
import org.apache.ivy.osgi.obr.xml.RequirementFilter;
public class RequirementFilterParser {
public static RequirementFilter parse(String text) throws ParseException {
return new Parser(text).parse();
}
static class Parser {
/**
* text to parse
*/
private final String text;
/**
* the length of the source
*/
private int length;
/**
* position in the source
*/
private int pos = 0;
/**
* last read character
*/
private char c;
/**
* Default constructor
*
* @param header
* the header to parse
*/
Parser(String text) {
this.text = text;
this.length = text.length();
}
/**
* Do the parsing
*
* @return
*
* @throws ParseException
*/
RequirementFilter parse() throws ParseException {
return parseFilter();
}
private char readNext() {
if (pos == length) {
c = '\0';
} else {
c = text.charAt(pos++);
}
return c;
}
private void unread() {
if (pos > 0) {
pos--;
}
}
private RequirementFilter parseFilter() throws ParseException {
skipWhiteSpace();
readNext();
if (c != '(') {
throw new ParseException("Expecting '(' as the start of the filter", pos);
}
switch (readNext()) {
case '&':
return parseAnd();
case '|':
return parseOr();
case '!':
return parseNot();
default:
unread();
return parseCompare();
}
}
private RequirementFilter parseCompare() throws ParseException {
String leftValue = parseCompareValue();
Operator operator = parseCompareOperator();
String rightValue = parseCompareValue();
readNext();
if (c != ')') {
throw new ParseException("Expecting ')' as the end of the filter", pos);
}
return new CompareFilter(leftValue, operator, rightValue);
}
private String parseCompareValue() {
StringBuilder builder = new StringBuilder();
do {
readNext();
if (!isOperator(c) && c != ')' && c != '(') {
builder.append(c);
} else {
unread();
break;
}
} while (pos < length);
return builder.toString();
}
private boolean isOperator(char ch) {
return ch == '=' || ch == '<' || ch == '>';
}
private Operator parseCompareOperator() throws ParseException {
switch (readNext()) {
case '=':
return Operator.EQUALS;
case '>':
if (readNext() == '=') {
return Operator.GREATER_OR_EQUAL;
}
unread();
return Operator.GREATER_THAN;
case '<':
if (readNext() == '=') {
return Operator.LOWER_OR_EQUAL;
}
unread();
return Operator.LOWER_THAN;
default:
break;
}
throw new ParseException("Expecting an operator: =, <, <=, > or >=", pos);
}
private RequirementFilter parseAnd() throws ParseException {
AndFilter filter = new AndFilter();
parseMultiOperator(filter);
return filter;
}
private RequirementFilter parseOr() throws ParseException {
OrFilter filter = new OrFilter();
parseMultiOperator(filter);
return filter;
}
private void parseMultiOperator(MultiOperatorFilter filter) throws ParseException {
do {
readNext();
if (c == '(') {
unread();
filter.add(parseFilter());
} else {
break;
}
} while (pos < length);
if (filter.getSubFilters().size() == 0) {
throw new ParseException("Expecting at least on sub filter", pos);
}
}
private RequirementFilter parseNot() throws ParseException {
readNext();
if (c != '(') {
throw new ParseException("The ! operator is expecting a filter", pos);
}
unread();
return new NotFilter(parseFilter());
}
private void skipWhiteSpace() {
do {
switch (readNext()) {
case ' ':
continue;
default:
unread();
return;
}
} while (pos < length);
}
}
}

View File

@ -0,0 +1,73 @@
/*
* 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.ivy.osgi.obr.filter;
import org.apache.ivy.osgi.obr.xml.RequirementFilter;
public abstract class UniOperatorFilter extends RequirementFilter {
private final RequirementFilter subFilter;
public UniOperatorFilter(RequirementFilter subFilter) {
this.subFilter = subFilter;
}
abstract protected char operator();
@Override
public void append(StringBuilder builder) {
builder.append("(");
builder.append(operator());
builder.append(subFilter.toString());
builder.append(")");
}
public RequirementFilter getSubFilter() {
return subFilter;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((subFilter == null) ? 0 : subFilter.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof MultiOperatorFilter)) {
return false;
}
UniOperatorFilter other = (UniOperatorFilter) obj;
if (subFilter == null) {
if (other.subFilter != null) {
return false;
}
} else if (!subFilter.equals(other.subFilter)) {
return false;
}
return true;
}
}

View File

@ -0,0 +1,44 @@
/*
* 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.ivy.osgi.obr.xml;
import java.util.ArrayList;
import java.util.List;
public class Capability {
private List<CapabilityProperty> properties = new ArrayList<CapabilityProperty>();
private String name;
public Capability(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void addProperty(String n, String value, String type) {
properties.add(new CapabilityProperty(n, value, type));
}
public List<CapabilityProperty> getProperties() {
return properties;
}
}

View File

@ -0,0 +1,98 @@
/*
* 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.ivy.osgi.obr.xml;
import java.text.ParseException;
import org.apache.ivy.osgi.core.BundleCapability;
import org.apache.ivy.osgi.core.BundleInfo;
import org.apache.ivy.osgi.core.ExportPackage;
import org.apache.ivy.osgi.util.Version;
import org.apache.ivy.util.Message;
public class CapabilityAdapter {
public static void adapt(BundleInfo bundleInfo, Capability capability) throws ParseException {
String name = capability.getName();
if (BundleInfo.PACKAGE_TYPE.equals(name)) {
ExportPackage exportPackage = getExportPackage(bundleInfo, capability);
bundleInfo.addCapability(exportPackage);
} else if (BundleInfo.BUNDLE_TYPE.equals(name)) {
// nothing to do, already handled at the resource tag level
} else if (BundleInfo.SERVICE_TYPE.equals(name)) {
BundleCapability service = getOSGiService(bundleInfo, capability);
bundleInfo.addCapability(service);
} else {
Message.warn("Unsupported capability '" + name + "' on the bundle '" + bundleInfo.getSymbolicName() + "'");
}
}
private static ExportPackage getExportPackage(BundleInfo bundleInfo, Capability capability) throws ParseException {
String pkgName = null;
Version version = null;
String uses = null;
for (CapabilityProperty property : capability.getProperties()) {
String propName = property.getName();
if ("package".equals(propName)) {
pkgName = property.getValue();
} else if ("version".equals(propName)) {
version = new Version(property.getValue());
} else if ("uses".equals(propName)) {
uses = property.getValue();
} else {
Message.warn("Unsupported property '" + propName + "' on the 'package' capability of the bundle '"
+ bundleInfo.getSymbolicName() + "'");
}
}
if (pkgName == null) {
throw new ParseException("No package name for the capability", 0);
}
ExportPackage exportPackage = new ExportPackage(pkgName, version);
if (uses != null) {
String[] split = uses.trim().split(",");
for (String u : split) {
exportPackage.addUse(u.trim());
}
}
return exportPackage;
}
private static BundleCapability getOSGiService(BundleInfo bundleInfo, Capability capability) throws ParseException {
String name = null;
Version version = null;
for (CapabilityProperty property : capability.getProperties()) {
String propName = property.getName();
if ("service".equals(propName)) {
name = property.getValue();
} else if ("version".equals(propName)) {
version = new Version(property.getValue());
} else {
Message.warn("Unsupported property '" + propName + "' on the 'package' capability of the bundle '"
+ bundleInfo.getSymbolicName() + "'");
}
}
if (name == null) {
throw new ParseException("No service name for the capability", 0);
}
BundleCapability service = new BundleCapability(BundleInfo.SERVICE_TYPE, name, version);
return service;
}
}

View File

@ -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.ivy.osgi.obr.xml;
public class CapabilityProperty {
private String name;
private String value;
private String type;
public CapabilityProperty(String name, String value, String type) {
this.name = name;
this.value = value;
this.type = type;
}
public String getName() {
return name;
}
public String getValue() {
return value;
}
public String getType() {
return type;
}
}

View File

@ -0,0 +1,402 @@
/*
* 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.ivy.osgi.obr.xml;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import org.apache.ivy.osgi.core.BundleInfo;
import org.apache.ivy.osgi.obr.filter.RequirementFilterParser;
import org.apache.ivy.osgi.repo.BundleRepo;
import org.apache.ivy.osgi.util.DelegetingHandler;
import org.apache.ivy.osgi.util.Version;
import org.apache.ivy.util.Message;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
public class OBRXMLParser {
static final String REPOSITORY = "repository";
static final String REPOSITORY_LASTMODIFIED = "lastmodified";
static final String REPOSITORY_NAME = "name";
static final String RESOURCE = "resource";
static final String RESOURCE_ID = "id";
static final String RESOURCE_PRESENTATION_NAME = "presentationname";
static final String RESOURCE_SYMBOLIC_NAME = "symbolicname";
static final String RESOURCE_URI = "uri";
static final String RESOURCE_VERSION = "version";
static final String CAPABILITY = "capability";
static final String CAPABILITY_NAME = "name";
static final String CAPABILITY_PROPERTY = "p";
static final String CAPABILITY_PROPERTY_NAME = "n";
static final String CAPABILITY_PROPERTY_VALUE = "v";
static final String CAPABILITY_PROPERTY_TYPE = "t";
static final String REQUIRE = "require";
static final String REQUIRE_NAME = "name";
static final String REQUIRE_OPTIONAL = "optional";
static final String REQUIRE_MULTIPLE = "multiple";
static final String REQUIRE_EXTEND = "extend";
static final String REQUIRE_FILTER = "filter";
static final String TRUE = "true";
static final String FALSE = "false";
public static BundleRepo parse(InputStream in) throws ParseException, IOException, SAXException {
XMLReader reader;
try {
reader = XMLReaderFactory.createXMLReader();
} catch (SAXException e) {
throw new ParseException(e.getMessage(), 0);
}
RepositoryHandler handler = new RepositoryHandler();
reader.setContentHandler(handler);
reader.parse(new InputSource(in));
return handler.repo;
}
private static class RepositoryHandler extends DelegetingHandler<DelegetingHandler<?>> {
BundleRepo repo;
public RepositoryHandler() {
super(REPOSITORY, null);
new ResourceHandler(this);
}
@Override
protected void handleAttributes(Attributes atts) {
repo = new BundleRepo();
repo.setName(atts.getValue(REPOSITORY_NAME));
String lastModified = atts.getValue(REPOSITORY_LASTMODIFIED);
try {
repo.setLastModified(Long.valueOf(lastModified));
} catch (NumberFormatException e) {
printWarning(this, "Incorrect last modified timestamp : " + lastModified + ". It will be ignored.");
}
}
}
private static class ResourceHandler extends DelegetingHandler<RepositoryHandler> {
BundleInfo bundleInfo;
public ResourceHandler(RepositoryHandler repositoryHandler) {
super(RESOURCE, repositoryHandler);
new ResourceDescriptionHandler(this);
new ResourceDocumentationHandler(this);
new ResourceLicenseHandler(this);
new ResourceSizeHandler(this);
new CapabilityHandler(this);
new RequireHandler(this);
}
@Override
protected void handleAttributes(Attributes atts) throws SAXException {
String symbolicname = atts.getValue(RESOURCE_SYMBOLIC_NAME);
if (symbolicname == null) {
printError(this, "Resource with no symobilc name, skipping it.");
skip();
return;
}
String v = atts.getValue(RESOURCE_VERSION);
Version version;
if (v == null) {
version = new Version(1, 0, 0, null);
} else {
try {
version = new Version(v);
} catch (NumberFormatException e) {
printError(this, "Incorrect resource version: " + v + ". The resource " + symbolicname
+ " is then ignored.");
skip();
return;
}
}
bundleInfo = new BundleInfo(symbolicname, version);
bundleInfo.setPresentationName(atts.getValue(RESOURCE_PRESENTATION_NAME));
bundleInfo.setUri(atts.getValue(RESOURCE_URI));
bundleInfo.setId(atts.getValue(RESOURCE_ID));
}
@Override
protected void doEndElement(String uri, String localName, String name) throws SAXException {
getParent().repo.addBundle(bundleInfo);
}
}
private static class ResourceDescriptionHandler extends DelegetingHandler<ResourceHandler> {
public ResourceDescriptionHandler(ResourceHandler resourceHandler) {
super("description", resourceHandler);
setBufferingChar(true);
}
@Override
protected void doEndElement(String uri, String localName, String name) throws SAXException {
getParent().bundleInfo.setDescription(getBufferedChars().trim());
}
}
private static class ResourceDocumentationHandler extends DelegetingHandler<ResourceHandler> {
public ResourceDocumentationHandler(ResourceHandler resourceHandler) {
super("documentation", resourceHandler);
setBufferingChar(true);
}
@Override
protected void doEndElement(String uri, String localName, String name) throws SAXException {
getParent().bundleInfo.setDocumentation(getBufferedChars().trim());
}
}
private static class ResourceLicenseHandler extends DelegetingHandler<ResourceHandler> {
public ResourceLicenseHandler(ResourceHandler resourceHandler) {
super("license", resourceHandler);
setBufferingChar(true);
}
@Override
protected void doEndElement(String uri, String localName, String name) throws SAXException {
getParent().bundleInfo.setLicense(getBufferedChars().trim());
}
}
private static class ResourceSizeHandler extends DelegetingHandler<ResourceHandler> {
public ResourceSizeHandler(ResourceHandler resourceHandler) {
super("size", resourceHandler);
setBufferingChar(true);
}
@Override
protected void doEndElement(String uri, String localName, String name) throws SAXException {
String size = getBufferedChars().trim();
try {
getParent().bundleInfo.setSize(Integer.valueOf(size));
} catch (NumberFormatException e) {
printWarning(this, "Invalid size for the bundle" + getParent().bundleInfo.getSymbolicName() + ": "
+ size + ". This size is then ignored.");
}
}
}
private static class CapabilityHandler extends DelegetingHandler<ResourceHandler> {
Capability capability;
public CapabilityHandler(ResourceHandler resourceHandler) {
super(CAPABILITY, resourceHandler);
new CapabilityPropertyHandler(this);
}
@Override
protected void handleAttributes(Attributes atts) throws SAXException {
String name = atts.getValue(CAPABILITY_NAME);
if (name == null) {
skipResourceOnError(this, "Capability with no name");
return;
}
capability = new Capability(name);
}
@Override
protected void doEndElement(String uri, String localName, String name) throws SAXException {
try {
CapabilityAdapter.adapt(getParent().bundleInfo, capability);
} catch (ParseException e) {
skipResourceOnError(this, "Invalid capability: " + e.getMessage());
}
}
}
private static class CapabilityPropertyHandler extends DelegetingHandler<CapabilityHandler> {
public CapabilityPropertyHandler(CapabilityHandler capabilityHandler) {
super(CAPABILITY_PROPERTY, capabilityHandler);
}
@Override
protected void handleAttributes(Attributes atts) throws SAXException {
String name = atts.getValue(CAPABILITY_PROPERTY_NAME);
if (name == null) {
skipResourceOnError(this, "Capability property with no name on a capability "
+ getParent().capability.getName());
return;
}
String value = atts.getValue(CAPABILITY_PROPERTY_VALUE);
if (value == null) {
skipResourceOnError(this, "Capability property with no value on a capability "
+ getParent().capability.getName());
return;
}
String type = atts.getValue(CAPABILITY_PROPERTY_TYPE);
getParent().capability.addProperty(name, value, type);
}
}
private static class RequireHandler extends DelegetingHandler<ResourceHandler> {
private Requirement requirement;
public RequireHandler(ResourceHandler resourceHandler) {
super(REQUIRE, resourceHandler);
}
@Override
protected void handleAttributes(Attributes atts) throws SAXException {
String name = atts.getValue(REQUIRE_NAME);
if (name == null) {
skipResourceOnError(this, "Requirement with no name");
return;
}
String filterText = atts.getValue(REQUIRE_FILTER);
RequirementFilter filter = null;
if (filterText != null) {
try {
filter = RequirementFilterParser.parse(filterText);
} catch (ParseException e) {
skipResourceOnError(this, "Requirement with illformed filter: " + filterText);
return;
}
}
Boolean optional = null;
try {
optional = parseBoolean(atts, REQUIRE_OPTIONAL);
} catch (ParseException e) {
skipResourceOnError(this, "Requirement with unrecognised optional: " + e.getMessage());
return;
}
Boolean multiple = null;
try {
multiple = parseBoolean(atts, REQUIRE_MULTIPLE);
} catch (ParseException e) {
skipResourceOnError(this, "Requirement with unrecognised multiple: " + e.getMessage());
return;
}
Boolean extend = null;
try {
extend = parseBoolean(atts, REQUIRE_EXTEND);
} catch (ParseException e) {
skipResourceOnError(this, "Requirement with unrecognised extend: " + e.getMessage());
return;
}
requirement = new Requirement(name, filter);
if (optional != null) {
requirement.setOptional(optional.booleanValue());
}
if (multiple != null) {
requirement.setMultiple(multiple.booleanValue());
}
if (extend != null) {
requirement.setExtend(extend.booleanValue());
}
}
@Override
protected void doEndElement(String uri, String localName, String name) throws SAXException {
try {
RequirementAdapter.adapt(getParent().bundleInfo, requirement);
} catch (UnsupportedFilterException e) {
skipResourceOnError(this, "Unsupported requirement filter: " + e.getMessage());
} catch (ParseException e) {
skipResourceOnError(this, "Error in the requirement filter on the bundle: " + e.getMessage());
}
}
}
private static Boolean parseBoolean(Attributes atts, String name) throws ParseException {
String v = atts.getValue(name);
if (v == null) {
return null;
}
if (TRUE.equalsIgnoreCase(v)) {
return true;
} else if (FALSE.equalsIgnoreCase(v)) {
return false;
} else {
throw new ParseException("Unparsable boolean value: " + v, 0);
}
}
private static void skipResourceOnError(DelegetingHandler<?> handler, String message) {
DelegetingHandler<?> resourceHandler = handler;
while (!(resourceHandler instanceof ResourceHandler)) {
resourceHandler = resourceHandler.getParent();
}
BundleInfo bundleInfo = ((ResourceHandler) resourceHandler).bundleInfo;
printError(handler, message + ". The resource " + bundleInfo.getSymbolicName() + " is then ignored.");
resourceHandler.skip();
}
private static void printError(DelegetingHandler<?> handler, String message) {
Message.error(getLocation(handler.getLocator()) + message);
}
private static void printWarning(DelegetingHandler<?> handler, String message) {
Message.warn(getLocation(handler.getLocator()) + message);
}
private static String getLocation(Locator locator) {
if (locator == null) {
return "";
}
return "[line " + locator.getLineNumber() + " col. " + locator.getColumnNumber() + "] ";
}
}

View File

@ -0,0 +1,252 @@
/*
* 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.ivy.osgi.obr.xml;
import java.io.OutputStream;
import java.text.ParseException;
import java.util.Set;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;
import org.apache.ivy.core.IvyContext;
import org.apache.ivy.osgi.core.BundleCapability;
import org.apache.ivy.osgi.core.BundleInfo;
import org.apache.ivy.osgi.core.BundleRequirement;
import org.apache.ivy.osgi.core.ExportPackage;
import org.apache.ivy.osgi.core.ManifestParser;
import org.apache.ivy.osgi.repo.ManifestAndLocation;
import org.apache.ivy.osgi.util.Version;
import org.apache.ivy.osgi.util.VersionRange;
import org.apache.ivy.util.Message;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import static org.apache.ivy.osgi.obr.xml.OBRXMLParser.CAPABILITY;
import static org.apache.ivy.osgi.obr.xml.OBRXMLParser.CAPABILITY_NAME;
import static org.apache.ivy.osgi.obr.xml.OBRXMLParser.CAPABILITY_PROPERTY;
import static org.apache.ivy.osgi.obr.xml.OBRXMLParser.CAPABILITY_PROPERTY_NAME;
import static org.apache.ivy.osgi.obr.xml.OBRXMLParser.CAPABILITY_PROPERTY_TYPE;
import static org.apache.ivy.osgi.obr.xml.OBRXMLParser.CAPABILITY_PROPERTY_VALUE;
import static org.apache.ivy.osgi.obr.xml.OBRXMLParser.REPOSITORY;
import static org.apache.ivy.osgi.obr.xml.OBRXMLParser.REQUIRE;
import static org.apache.ivy.osgi.obr.xml.OBRXMLParser.REQUIRE_FILTER;
import static org.apache.ivy.osgi.obr.xml.OBRXMLParser.REQUIRE_NAME;
import static org.apache.ivy.osgi.obr.xml.OBRXMLParser.REQUIRE_OPTIONAL;
import static org.apache.ivy.osgi.obr.xml.OBRXMLParser.RESOURCE;
import static org.apache.ivy.osgi.obr.xml.OBRXMLParser.RESOURCE_SYMBOLIC_NAME;
import static org.apache.ivy.osgi.obr.xml.OBRXMLParser.RESOURCE_URI;
import static org.apache.ivy.osgi.obr.xml.OBRXMLParser.RESOURCE_VERSION;
import static org.apache.ivy.osgi.obr.xml.OBRXMLParser.TRUE;
public class OBRXMLWriter {
public static ContentHandler newHandler(OutputStream out, String encoding, boolean indent)
throws TransformerConfigurationException {
SAXTransformerFactory tf = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
TransformerHandler hd = tf.newTransformerHandler();
Transformer serializer = tf.newTransformer();
StreamResult stream = new StreamResult(out);
serializer.setOutputProperty(OutputKeys.ENCODING, encoding);
serializer.setOutputProperty(OutputKeys.INDENT, indent ? "yes" : "no");
hd.setResult(stream);
return hd;
}
public static void writeManifests(Iterable<ManifestAndLocation> it, ContentHandler handler, boolean quiet)
throws SAXException {
int level = quiet ? Message.MSG_DEBUG : Message.MSG_WARN;
handler.startDocument();
AttributesImpl atts = new AttributesImpl();
handler.startElement("", REPOSITORY, REPOSITORY, atts);
int nbOk = 0;
int nbRejected = 0;
for (ManifestAndLocation manifestAndLocation : it) {
BundleInfo bundleInfo;
try {
bundleInfo = ManifestParser.parseManifest(manifestAndLocation.getManifest());
bundleInfo.setUri(manifestAndLocation.getLocation());
nbOk++;
} catch (ParseException e) {
nbRejected++;
IvyContext.getContext().getMessageLogger().log(
"Rejected " + manifestAndLocation.getLocation() + ": " + e.getMessage(), level);
continue;
}
saxBundleInfo(bundleInfo, handler);
}
handler.endElement("", REPOSITORY, REPOSITORY);
handler.endDocument();
Message.info(nbOk + " bundle" + (nbOk > 1 ? "s" : "") + " added, " + nbRejected + " bundle"
+ (nbRejected > 1 ? "s" : "") + " rejected.");
}
public static void writeBundles(Iterable<BundleInfo> it, ContentHandler handler) throws SAXException {
handler.startDocument();
AttributesImpl atts = new AttributesImpl();
handler.startElement("", REPOSITORY, REPOSITORY, atts);
for (BundleInfo bundleInfo : it) {
saxBundleInfo(bundleInfo, handler);
}
handler.endElement("", REPOSITORY, REPOSITORY);
handler.endDocument();
}
private static void saxBundleInfo(BundleInfo bundleInfo, ContentHandler handler)
throws SAXException {
AttributesImpl atts = new AttributesImpl();
addAttr(atts, RESOURCE_SYMBOLIC_NAME, bundleInfo.getSymbolicName());
addAttr(atts, RESOURCE_VERSION, bundleInfo.getRawVersion());
if (bundleInfo.getUri() != null) {
addAttr(atts, RESOURCE_URI, bundleInfo.getUri());
}
handler.startElement("", RESOURCE, RESOURCE, atts);
for (BundleCapability capability : bundleInfo.getCapabilities()) {
saxCapability(capability, handler);
}
for (BundleRequirement requirement : bundleInfo.getRequirements()) {
saxRequirement(requirement, handler);
}
handler.endElement("", RESOURCE, RESOURCE);
handler.characters("\n".toCharArray(), 0, 1);
}
private static void saxCapability(BundleCapability capability, ContentHandler handler) throws SAXException {
AttributesImpl atts = new AttributesImpl();
String type = capability.getType();
addAttr(atts, CAPABILITY_NAME, type);
handler.startElement("", CAPABILITY, CAPABILITY, atts);
if (type.equals(BundleInfo.BUNDLE_TYPE)) {
// nothing to do, already handled with the resource tag
} else if (type.equals(BundleInfo.PACKAGE_TYPE)) {
saxCapabilityProperty("package", capability.getName(), handler);
Version v = capability.getRawVersion();
if (v != null) {
saxCapabilityProperty("version", v.toString(), handler);
}
Set<String> uses = ((ExportPackage) capability).getUses();
if (uses != null && !uses.isEmpty()) {
StringBuilder builder = new StringBuilder();
for (String use : uses) {
if (builder.length() != 0) {
builder.append(',');
}
builder.append(use);
}
saxCapabilityProperty("uses", builder.toString(), handler);
}
} else if (type.equals(BundleInfo.SERVICE_TYPE)) {
saxCapabilityProperty("service", capability.getName(), handler);
Version v = capability.getRawVersion();
if (v != null) {
saxCapabilityProperty("version", v.toString(), handler);
}
} else {
// oups
}
handler.endElement("", CAPABILITY, CAPABILITY);
handler.characters("\n".toCharArray(), 0, 1);
}
private static void saxCapabilityProperty(String n, String v, ContentHandler handler) throws SAXException {
saxCapabilityProperty(n, null, v, handler);
}
private static void saxCapabilityProperty(String n, String t, String v, ContentHandler handler) throws SAXException {
AttributesImpl atts = new AttributesImpl();
addAttr(atts, CAPABILITY_PROPERTY_NAME, n);
if (t != null) {
addAttr(atts, CAPABILITY_PROPERTY_TYPE, t);
}
addAttr(atts, CAPABILITY_PROPERTY_VALUE, v);
handler.startElement("", CAPABILITY_PROPERTY, CAPABILITY_PROPERTY, atts);
handler.endElement("", CAPABILITY_PROPERTY, CAPABILITY_PROPERTY);
handler.characters("\n".toCharArray(), 0, 1);
}
private static void saxRequirement(BundleRequirement requirement, ContentHandler handler) throws SAXException {
AttributesImpl atts = new AttributesImpl();
addAttr(atts, REQUIRE_NAME, requirement.getType());
if ("optional".equals(requirement.getResolution())) {
addAttr(atts, REQUIRE_OPTIONAL, TRUE);
}
addAttr(atts, REQUIRE_FILTER, buildFilter(requirement));
handler.startElement("", REQUIRE, REQUIRE, atts);
handler.endElement("", REQUIRE, REQUIRE);
handler.characters("\n".toCharArray(), 0, 1);
}
private static String buildFilter(BundleRequirement requirement) {
StringBuilder filter = new StringBuilder();
VersionRange v = requirement.getVersion();
if (v != null) {
appendVersion(filter, v);
}
filter.append('(');
filter.append(requirement.getType());
filter.append("=");
filter.append(requirement.getName());
filter.append(')');
if (v != null) {
filter.append(')');
}
return filter.toString();
}
private static void appendVersion(StringBuilder filter, VersionRange v) {
filter.append("(&");
Version start = v.getStartVersion();
if (start != null) {
filter.append("(version>");
if (!v.isStartExclusive()) {
filter.append('=');
}
filter.append(start.toString());
filter.append(')');
}
Version end = v.getEndVersion();
if (end != null) {
filter.append("(version<");
if (!v.isEndExclusive()) {
filter.append('=');
}
filter.append(end.toString());
filter.append(')');
}
}
private static void addAttr(AttributesImpl atts, String name, String value) {
if (value != null) {
atts.addAttribute("", name, name, "CDATA", value);
}
}
private static void addAttr(AttributesImpl atts, String name, Object value) {
if (value != null) {
atts.addAttribute("", name, name, "CDATA", value.toString());
}
}
}

View File

@ -0,0 +1,70 @@
/*
* 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.ivy.osgi.obr.xml;
public class Requirement {
private final String name;
private boolean optional;
private final RequirementFilter filter;
private boolean multiple = false;
private boolean extend = false;
public Requirement(String name, RequirementFilter filter) {
this.name = name;
this.filter = filter;
}
public String getName() {
return name;
}
public RequirementFilter getFilter() {
return filter;
}
public void setOptional(boolean optional) {
this.optional = optional;
}
public boolean isOptional() {
return optional;
}
public void setExtend(boolean extend) {
this.extend = extend;
}
public boolean isExtend() {
return extend;
}
public void setMultiple(boolean multiple) {
this.multiple = multiple;
}
public boolean isMultiple() {
return multiple;
}
}

View File

@ -0,0 +1,175 @@
/*
* 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.ivy.osgi.obr.xml;
import java.text.ParseException;
import org.apache.ivy.osgi.core.BundleInfo;
import org.apache.ivy.osgi.core.BundleRequirement;
import org.apache.ivy.osgi.obr.filter.AndFilter;
import org.apache.ivy.osgi.obr.filter.CompareFilter;
import org.apache.ivy.osgi.obr.filter.NotFilter;
import org.apache.ivy.osgi.obr.filter.CompareFilter.Operator;
import org.apache.ivy.osgi.util.Version;
import org.apache.ivy.osgi.util.VersionRange;
public class RequirementAdapter {
private Version startVersion = null;
private boolean startExclusive = false;
private Version endVersion = null;
private boolean endExclusive = false;
private String type = null;
private String name = null;
public static void adapt(BundleInfo info, Requirement requirement) throws UnsupportedFilterException,
ParseException {
RequirementAdapter adapter = new RequirementAdapter();
adapter.extractFilter(requirement.getFilter());
adapter.adapt(info, requirement.isOptional());
}
private void extractFilter(RequirementFilter filter) throws UnsupportedFilterException, ParseException {
if (filter instanceof AndFilter) {
AndFilter andFilter = (AndFilter) filter;
for (RequirementFilter subFilter : andFilter.getSubFilters()) {
extractFilter(subFilter);
}
} else if (filter instanceof CompareFilter) {
CompareFilter compareFilter = ((CompareFilter) filter);
parseCompareFilter(compareFilter, false);
} else if (filter instanceof NotFilter) {
NotFilter notFilter = ((NotFilter) filter);
if (notFilter.getSubFilter() instanceof CompareFilter) {
CompareFilter compareFilter = ((CompareFilter) notFilter.getSubFilter());
parseCompareFilter(compareFilter, true);
}
} else {
throw new UnsupportedFilterException("Unsupported filter: " + filter.getClass().getName());
}
}
private void adapt(BundleInfo info, boolean optional) throws ParseException {
VersionRange range = getVersionRange();
String resolution = optional ? "optional" : null;
if (type == null) {
throw new ParseException("No requirement actually specified", 0);
}
BundleRequirement requirement = new BundleRequirement(type, name, range, resolution);
info.addRequirement(requirement);
}
private VersionRange getVersionRange() {
VersionRange range = null;
if (startVersion != null || endVersion != null) {
range = new VersionRange(startExclusive, startVersion, endExclusive, endVersion);
}
return range;
}
private void parseCompareFilter(CompareFilter compareFilter, boolean not) throws UnsupportedFilterException {
String att = compareFilter.getLeftValue();
if (BundleInfo.PACKAGE_TYPE.equals(att) || BundleInfo.BUNDLE_TYPE.equals(att) || "symbolicname".equals(att)
|| BundleInfo.SERVICE_TYPE.equals(att)) {
if (not) {
throw new UnsupportedFilterException("Not filter on requirement comparaison is not supported");
}
if (type != null) {
throw new UnsupportedFilterException("Multiple requirement type are not supported");
}
if ("symbolicname".equals(att)) {
type = BundleInfo.BUNDLE_TYPE;
} else {
type = att;
}
if (compareFilter.getOperator() != Operator.EQUALS) {
throw new UnsupportedFilterException("Filtering is only supported with the operator '='");
}
name = compareFilter.getRightValue();
} else if ("version".equals(att)) {
String v = compareFilter.getRightValue();
Operator operator = compareFilter.getOperator();
if (not) {
switch (operator) {
case EQUALS:
throw new UnsupportedFilterException("Not filter on equals comparaison is not supported");
case GREATER_OR_EQUAL:
operator = Operator.LOWER_THAN;
break;
case GREATER_THAN:
operator = Operator.LOWER_OR_EQUAL;
break;
case LOWER_OR_EQUAL:
operator = Operator.GREATER_THAN;
break;
case LOWER_THAN:
operator = Operator.GREATER_OR_EQUAL;
break;
}
}
switch (operator) {
case EQUALS:
if (startVersion != null || endVersion != null) {
throw new UnsupportedFilterException("Multiple version matching is not supported");
}
startVersion = new Version(v);
startExclusive = false;
endVersion = new Version(v);
endExclusive = false;
break;
case GREATER_OR_EQUAL:
if (startVersion != null) {
throw new UnsupportedFilterException("Multiple version matching is not supported");
}
startVersion = new Version(v);
startExclusive = false;
break;
case GREATER_THAN:
if (startVersion != null) {
throw new UnsupportedFilterException("Multiple version matching is not supported");
}
startVersion = new Version(v);
startExclusive = true;
break;
case LOWER_OR_EQUAL:
if (endVersion != null) {
throw new UnsupportedFilterException("Multiple version matching is not supported");
}
endVersion = new Version(v);
endExclusive = false;
break;
case LOWER_THAN:
if (endVersion != null) {
throw new UnsupportedFilterException("Multiple version matching is not supported");
}
endVersion = new Version(v);
endExclusive = true;
break;
}
} else {
throw new UnsupportedFilterException("Unsupported attribute: " + att);
}
}
}

View File

@ -0,0 +1,31 @@
/*
* 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.ivy.osgi.obr.xml;
public abstract class RequirementFilter {
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
append(builder);
return builder.toString();
}
public abstract void append(StringBuilder builder);
}

View File

@ -0,0 +1,25 @@
/*
* 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.ivy.osgi.obr.xml;
public class UnsupportedFilterException extends Exception {
public UnsupportedFilterException(String message) {
super(message);
}
}

View File

@ -0,0 +1,137 @@
/*
* 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.ivy.osgi.repo;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Stack;
import java.util.jar.JarInputStream;
import java.util.jar.Manifest;
import org.apache.ivy.util.Message;
public abstract class AbstractFSManifestIterable implements Iterable<ManifestAndLocation> {
public Iterator<ManifestAndLocation> iterator() {
return new FSManifestIterator();
}
abstract protected List<String> listBundleFiles(String dir) throws IOException;
abstract protected List<String> listDirs(String dir) throws IOException;
abstract protected InputStream getInputStream(String f) throws IOException;
protected String createBundleLocation(String location) {
return location;
}
class FSManifestIterator implements Iterator<ManifestAndLocation> {
private ManifestAndLocation next = null;
/**
* Stack of list of directories. An iterator in the stack represents the current directory being lookup. The
* first element in the stack is the root directory. The next element in the stack is an iterator on the
* children on the root. The last iterator in the stack points to {@link #currentDir}.
*/
private Stack<Iterator<String>> dirs = new Stack<Iterator<String>>();
/**
* The bundles files being lookup.
*/
private Iterator<String> bundleCandidates = null;
private String currentDir = null;
FSManifestIterator() {
dirs.add(Collections.singleton("").iterator());
}
/**
* Deep first tree lookup for the directories and the bundles are searched on each found directory.
*/
public boolean hasNext() {
while (next == null) {
// no current directory
if (currentDir == null) {
// so get the next one
if (dirs.peek().hasNext()) {
currentDir = dirs.peek().next();
try {
bundleCandidates = listBundleFiles(currentDir).iterator();
} catch (IOException e) {
Message.warn("Unlistable dir: " + currentDir + " (" + e + ")");
currentDir = null;
}
} else if (dirs.size() <= 1) {
// no next directory, but we are at the root: finished
return false;
} else {
// remove the top of the stack and continue with a sibling.
dirs.pop();
}
} else if (bundleCandidates.hasNext()) {
String bundleCandidate = bundleCandidates.next();
try {
JarInputStream in = new JarInputStream(getInputStream(bundleCandidate));
Manifest manifest = in.getManifest();
if (manifest != null) {
next = new ManifestAndLocation(manifest, createBundleLocation(bundleCandidate));
} else {
Message.debug("No manifest in jar: " + bundleCandidate);
}
} catch (FileNotFoundException e) {
Message.debug("Jar file just removed: " + bundleCandidate + " (" + e + ")");
} catch (IOException e) {
Message.warn("Unreadable jar: " + bundleCandidate + " (" + e + ")");
}
} else {
// no more candidate on the current directory
// so lookup in the children directories
try {
dirs.add(listDirs(currentDir).iterator());
} catch (IOException e) {
Message.warn("Unlistable dir: " + currentDir + " (" + e + ")");
dirs.add(Collections.<String> emptyList().iterator());
}
currentDir = null;
}
}
return true;
}
public ManifestAndLocation next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
ManifestAndLocation manifest = next;
next = null;
return manifest;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
}

View File

@ -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.ivy.osgi.repo;
import org.apache.ivy.osgi.core.BundleInfo;
import org.apache.ivy.osgi.util.Version;
public class BundleCapabilityAndLocation {
private final String name;
private final Version version;
private final BundleInfo bundleInfo;
private final String type;
public BundleCapabilityAndLocation(String type, String name, Version version, BundleInfo bundleInfo) {
this.type = type;
this.name = name;
this.version = version;
this.bundleInfo = bundleInfo;
}
public BundleInfo getBundleInfo() {
return bundleInfo;
}
public String getName() {
return name;
}
public String getType() {
return type;
}
public Version getVersion() {
return version;
}
}

View File

@ -0,0 +1,294 @@
/*
* 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.ivy.osgi.repo;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.ivy.core.module.descriptor.Artifact;
import org.apache.ivy.core.module.descriptor.Configuration;
import org.apache.ivy.core.module.descriptor.DefaultArtifact;
import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor;
import org.apache.ivy.core.module.descriptor.DefaultExcludeRule;
import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor;
import org.apache.ivy.core.module.descriptor.Configuration.Visibility;
import org.apache.ivy.core.module.id.ArtifactId;
import org.apache.ivy.core.module.id.ModuleId;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.osgi.core.BundleInfo;
import org.apache.ivy.osgi.core.BundleRequirement;
import org.apache.ivy.osgi.core.ExportPackage;
import org.apache.ivy.osgi.repo.osgi.ExecutionEnvironmentProfileProvider;
import org.apache.ivy.osgi.util.Version;
import org.apache.ivy.osgi.util.VersionRange;
import org.apache.ivy.plugins.matcher.ExactOrRegexpPatternMatcher;
import org.apache.ivy.plugins.matcher.PatternMatcher;
import org.apache.ivy.util.Message;
import org.apache.ivy.util.StringUtils;
public class BundleInfoAdapter {
public static final String CONF_NAME_DEFAULT = "default";
public static final Configuration CONF_DEFAULT = new Configuration(CONF_NAME_DEFAULT);
public static final String CONF_NAME_OPTIONAL = "optional";
public static final Configuration CONF_OPTIONAL = new Configuration(CONF_NAME_OPTIONAL, Visibility.PUBLIC,
"Optional dependencies", new String[] { CONF_NAME_DEFAULT }, true, null);
public static final String CONF_NAME_TRANSITIVE_OPTIONAL = "transitive-optional";
public static final Configuration CONF_TRANSITIVE_OPTIONAL = new Configuration(CONF_NAME_TRANSITIVE_OPTIONAL,
Visibility.PUBLIC, "Optional dependencies", new String[] { CONF_NAME_OPTIONAL }, true, null);
public static final String CONF_USE_PREFIX = "use_";
public static final String EXTRA_ATTRIBUTE_NAME = "osgi";
public static final Map<String, String> OSGI_BUNDLE = Collections.singletonMap(EXTRA_ATTRIBUTE_NAME,
BundleInfo.BUNDLE_TYPE);
public static final Map<String, String> OSGI_PACKAGE = Collections.singletonMap(EXTRA_ATTRIBUTE_NAME,
BundleInfo.PACKAGE_TYPE);
public static final Map<String, String> OSGI_SERVICE = Collections.singletonMap(EXTRA_ATTRIBUTE_NAME,
BundleInfo.SERVICE_TYPE);
public static DefaultModuleDescriptor toModuleDescriptor(BundleInfo bundle,
ExecutionEnvironmentProfileProvider profileProvider) throws ProfileNotFoundException {
DefaultModuleDescriptor md = new DefaultModuleDescriptor(null, null);
ModuleRevisionId mrid = asMrid(bundle.getSymbolicName(), bundle.getVersion(), OSGI_BUNDLE);
md.setResolvedPublicationDate(new Date());
md.setModuleRevisionId(mrid);
md.addConfiguration(CONF_DEFAULT);
md.addConfiguration(CONF_OPTIONAL);
md.addConfiguration(CONF_TRANSITIVE_OPTIONAL);
Set<String> exportedPkgNames = new HashSet<String>(bundle.getExports().size());
for (ExportPackage exportPackage : bundle.getExports()) {
exportedPkgNames.add(exportPackage.getName());
String[] confDependencies = new String[exportPackage.getUses().size() + 1];
int i = 0;
for (String use : exportPackage.getUses()) {
confDependencies[i++] = CONF_USE_PREFIX + use;
}
confDependencies[i] = CONF_NAME_DEFAULT;
md.addConfiguration(new Configuration(CONF_USE_PREFIX + exportPackage.getName(), Visibility.PUBLIC,
"Exported package " + exportPackage.getName(), confDependencies, true, null));
}
requirementAsDependency(md, bundle, exportedPkgNames);
if (bundle.getUri() != null) {
DefaultArtifact artifact = null;
String uri = bundle.getUri();
if (uri.startsWith("ivy://")) {
artifact = decodeIvyLocation(uri);
} else {
URL url = null;
try {
url = new URL("file:" + uri);
} catch (MalformedURLException e) {
Message.error("BUG IN BUSHEL, please report: " + e.getMessage() + "\n"
+ StringUtils.getStackTrace(e));
}
if (url != null) {
artifact = new DefaultArtifact(mrid, null, bundle.getSymbolicName(), "jar", "jar", url, null);
}
}
if (artifact != null) {
md.addArtifact(CONF_NAME_DEFAULT, artifact);
}
}
if (profileProvider != null) {
for (String env : bundle.getExecutionEnvironments()) {
ExecutionEnvironmentProfile profile = profileProvider.getProfile(env);
if (profile == null) {
throw new ProfileNotFoundException("Execution environment profile " + env + " not found");
}
for (String pkg : profile.getPkgNames()) {
ArtifactId id = new ArtifactId(ModuleId.newInstance("", pkg), PatternMatcher.ANY_EXPRESSION,
PatternMatcher.ANY_EXPRESSION, PatternMatcher.ANY_EXPRESSION);
DefaultExcludeRule rule = new DefaultExcludeRule(id, ExactOrRegexpPatternMatcher.INSTANCE,
OSGI_PACKAGE);
String[] confs = md.getConfigurationsNames();
for (int i = 0; i < confs.length; i++) {
rule.addConfiguration(confs[i]);
}
md.addExcludeRule(rule);
}
}
}
return md;
}
public static String encodeIvyLocation(Artifact artifact) {
ModuleRevisionId mrid = artifact.getModuleRevisionId();
return encodeIvyLocation(mrid.getOrganisation(), mrid.getName(), mrid.getBranch(), mrid.getRevision(), artifact
.getType(), artifact.getName(), artifact.getExt());
}
private static String encodeIvyLocation(String org, String name, String branch, String rev, String type,
String art, String ext) {
StringBuilder builder = new StringBuilder();
builder.append("ivy://");
builder.append(org);
builder.append('/');
builder.append(name);
builder.append('?');
if (branch != null) {
builder.append("branch=");
builder.append(branch);
}
if (rev != null) {
builder.append("&rev=");
builder.append(rev);
}
if (type != null) {
builder.append("&type=");
builder.append(type);
}
if (art != null) {
builder.append("&art=");
builder.append(art);
}
if (ext != null) {
builder.append("&ext=");
builder.append(ext);
}
return builder.toString();
}
private static DefaultArtifact decodeIvyLocation(String uri) {
String org = null;
String name = null;
String branch = null;
String rev = null;
String art = null;
String type = null;
String ext = null;
uri = uri.substring(6);
int i = uri.indexOf('/');
if (i < 0) {
throw new IllegalArgumentException("Expecting an organisation in the ivy uri: " + uri);
}
org = uri.substring(0, i);
uri = uri.substring(i + 1);
i = uri.indexOf('?');
if (i < 0) {
throw new IllegalArgumentException("Expecting an module name in the ivy uri: " + uri);
}
name = uri.substring(0, i);
uri = uri.substring(i + 1);
String[] parameters = uri.split("&");
for (String parameter : parameters) {
String[] nameAndValue = parameter.split("=");
if (nameAndValue.length != 2) {
throw new IllegalArgumentException("Malformed query string in the ivy uri: " + uri);
} else if (nameAndValue[0].equals("branch")) {
branch = nameAndValue[1];
} else if (nameAndValue[0].equals("rev")) {
rev = nameAndValue[1];
} else if (nameAndValue[0].equals("art")) {
art = nameAndValue[1];
} else if (nameAndValue[0].equals("type")) {
type = nameAndValue[1];
} else if (nameAndValue[0].equals("ext")) {
ext = nameAndValue[1];
} else {
throw new IllegalArgumentException("Unrecognized parameter '" + nameAndValue[0]
+ " in the query string of the ivy uri: " + uri);
}
}
ModuleRevisionId amrid = ModuleRevisionId.newInstance(org, name, branch, rev);
DefaultArtifact artifact = new DefaultArtifact(amrid, null, art, type, ext);
return artifact;
}
private static void requirementAsDependency(DefaultModuleDescriptor md, BundleInfo bundleInfo,
Set<String> exportedPkgNames) {
for (BundleRequirement requirement : bundleInfo.getRequirements()) {
String type = requirement.getType();
String name = requirement.getName();
if (type.equals(BundleInfo.PACKAGE_TYPE) && exportedPkgNames.contains(name)) {
// don't declare package exported by the current bundle
continue;
}
Map<String, String> osgiAtt = Collections.singletonMap(EXTRA_ATTRIBUTE_NAME, type);
ModuleRevisionId ddmrid = asMrid(name, requirement.getVersion(), osgiAtt);
DefaultDependencyDescriptor dd = new DefaultDependencyDescriptor(ddmrid, false);
String conf = CONF_NAME_DEFAULT;
if (type.equals(BundleInfo.PACKAGE_TYPE)) {
// declare the configuration for the package
conf = CONF_USE_PREFIX + name;
md.addConfiguration(new Configuration(CONF_USE_PREFIX + name, Visibility.PUBLIC, "Exported package "
+ name, new String[] { CONF_NAME_DEFAULT }, true, null));
dd.addDependencyConfiguration(conf, conf);
}
if ("optional".equals(requirement.getResolution())) {
dd.addDependencyConfiguration(CONF_NAME_OPTIONAL, conf);
dd.addDependencyConfiguration(CONF_NAME_TRANSITIVE_OPTIONAL, CONF_NAME_TRANSITIVE_OPTIONAL);
} else {
dd.addDependencyConfiguration(CONF_NAME_DEFAULT, conf);
}
md.addDependency(dd);
}
}
private static ModuleRevisionId asMrid(String symbolicNAme, Version v, Map<String, String> extraAttr) {
return ModuleRevisionId.newInstance("", symbolicNAme, v == null ? null : v.toString(), extraAttr);
}
private static ModuleRevisionId asMrid(String symbolicNAme, VersionRange v, Map<String, String> extraAttr) {
String revision;
if (v == null) {
revision = "[0,)";
} else {
revision = v.toIvyRevision();
}
return ModuleRevisionId.newInstance("", symbolicNAme, revision, extraAttr);
}
public static class ProfileNotFoundException extends RuntimeException {
public ProfileNotFoundException(String msg) {
super(msg);
}
}
}

View File

@ -0,0 +1,146 @@
/*
* 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.ivy.osgi.repo;
import java.text.ParseException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.ivy.osgi.core.BundleCapability;
import org.apache.ivy.osgi.core.BundleInfo;
import org.apache.ivy.osgi.core.ManifestParser;
import org.apache.ivy.osgi.util.Version;
import org.apache.ivy.util.Message;
public class BundleRepo {
private String name;
private Long lastModified;
private final Set<BundleInfo> bundles = new HashSet<BundleInfo>();
private final Map<String, Map<String, Set<BundleCapabilityAndLocation>>> bundleByCapabilities = new HashMap<String, Map<String, Set<BundleCapabilityAndLocation>>>();
public BundleRepo() {
// default constructor
}
public BundleRepo(Iterable<ManifestAndLocation> it) {
populate(it);
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setLastModified(Long lastModified) {
this.lastModified = lastModified;
}
public Long getLastModified() {
return lastModified;
}
public void populate(Iterable<ManifestAndLocation> it) {
for (ManifestAndLocation manifestAndLocation : it) {
try {
BundleInfo bundleInfo = ManifestParser.parseManifest(manifestAndLocation.getManifest());
bundleInfo.setUri(manifestAndLocation.getLocation());
addBundle(bundleInfo);
} catch (ParseException e) {
Message.error("Rejected " + manifestAndLocation.getLocation() + ": " + e.getMessage());
}
}
}
public void addBundle(BundleInfo bundleInfo) {
bundles.add(bundleInfo);
populateCapabilities(BundleInfo.BUNDLE_TYPE, bundleInfo.getSymbolicName(), bundleInfo.getVersion(), bundleInfo);
for (BundleCapability capability : bundleInfo.getCapabilities()) {
populateCapabilities(capability.getType(), capability.getName(), capability.getVersion(), bundleInfo);
}
}
private void populateCapabilities(String type, String n, Version version, BundleInfo bundleInfo) {
Map<String, Set<BundleCapabilityAndLocation>> map = bundleByCapabilities.get(type);
if (map == null) {
map = new HashMap<String, Set<BundleCapabilityAndLocation>>();
bundleByCapabilities.put(type, map);
}
Set<BundleCapabilityAndLocation> bundleReferences = map.get(n);
if (bundleReferences == null) {
bundleReferences = new HashSet<BundleCapabilityAndLocation>();
map.put(n, bundleReferences);
}
if (!bundleReferences.add(new BundleCapabilityAndLocation(type, n, version, bundleInfo))) {
Message.warn("The repo did already contains " + n + "#" + version);
}
}
public Set<BundleInfo> getBundles() {
return bundles;
}
public Map<String, Map<String, Set<BundleCapabilityAndLocation>>> getBundleByCapabilities() {
return bundleByCapabilities;
}
@Override
public String toString() {
return bundles.toString();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((bundles == null) ? 0 : bundles.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof BundleRepo)) {
return false;
}
BundleRepo other = (BundleRepo) obj;
if (bundles == null) {
if (other.bundles != null) {
return false;
}
} else if (!bundles.equals(other.bundles)) {
return false;
}
return true;
}
}

View File

@ -0,0 +1,633 @@
/*
* 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.ivy.osgi.repo;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import org.apache.ivy.core.IvyContext;
import org.apache.ivy.core.IvyPatternHelper;
import org.apache.ivy.core.module.descriptor.Artifact;
import org.apache.ivy.core.module.descriptor.Configuration;
import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor;
import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
import org.apache.ivy.core.module.descriptor.MDArtifact;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.core.report.DownloadStatus;
import org.apache.ivy.core.report.MetadataArtifactDownloadReport;
import org.apache.ivy.core.resolve.IvyNode;
import org.apache.ivy.core.resolve.ResolveData;
import org.apache.ivy.core.resolve.ResolvedModuleRevision;
import org.apache.ivy.osgi.core.BundleInfo;
import org.apache.ivy.osgi.obr.xml.OBRXMLParser;
import org.apache.ivy.osgi.repo.osgi.ExecutionEnvironmentProfileProvider;
import org.apache.ivy.osgi.util.Version;
import org.apache.ivy.plugins.conflict.ConflictManager;
import org.apache.ivy.plugins.latest.ArtifactInfo;
import org.apache.ivy.plugins.repository.Repository;
import org.apache.ivy.plugins.repository.Resource;
import org.apache.ivy.plugins.repository.file.FileRepository;
import org.apache.ivy.plugins.resolver.BasicResolver;
import org.apache.ivy.plugins.resolver.util.ResolvedResource;
import org.apache.ivy.plugins.version.VersionMatcher;
import org.apache.ivy.util.Message;
import org.xml.sax.SAXException;
public class BundleRepoResolver extends BasicResolver {
private Repository repository = null;
private String repoXmlURL;
private String repoXmlFile;
private BundleRepo repoDescriptor = null;
private ExecutionEnvironmentProfileProvider profileProvider;
public enum RequirementStrategy {
// take the first matching
first,
// if there are any ambiguity, fail to resolve
noambiguity
}
private RequirementStrategy requirementStrategy = RequirementStrategy.noambiguity;
public void setImportPackageStrategy(RequirementStrategy importPackageStrategy) {
this.requirementStrategy = importPackageStrategy;
}
public void setImportPackageStrategy(String strategy) {
setImportPackageStrategy(RequirementStrategy.valueOf(strategy));
}
public void setRepoXmlFile(String repositoryXmlFile) {
this.repoXmlFile = repositoryXmlFile;
}
public void setRepoXmlURL(String repositoryXmlURL) {
this.repoXmlURL = repositoryXmlURL;
}
public void add(ExecutionEnvironmentProfileProvider pp) {
this.profileProvider = pp;
}
private void ensureInit() {
if (repoDescriptor != null && repository != null) {
return;
}
if (repoDescriptor != null || repository != null) {
throw new IllegalStateException("The osgi repository resolver " + getName()
+ " wasn't correctly configured, see previous error in the logs");
}
if (repoXmlFile != null && repoXmlURL != null) {
throw new RuntimeException("The osgi repository resolver " + getName()
+ " couldn't be configured: repoXmlFile and repoXmlUrl cannot be set both");
}
if (repoXmlFile != null) {
File f = new File(repoXmlFile);
repository = new FileRepository(f.getParentFile());
FileInputStream in;
try {
in = new FileInputStream(f);
} catch (FileNotFoundException e) {
throw new RuntimeException("The osgi repository resolver " + getName()
+ " couldn't be configured: the file " + repoXmlFile + " was not found");
}
try {
repoDescriptor = OBRXMLParser.parse(in);
} catch (ParseException e) {
throw new RuntimeException("The osgi repository resolver " + getName()
+ " couldn't be configured: the file " + repoXmlFile + " is incorrectly formed ("
+ e.getMessage() + ")");
} catch (IOException e) {
throw new RuntimeException("The osgi repository resolver " + getName()
+ " couldn't be configured: the file " + repoXmlFile + " could not be read (" + e.getMessage()
+ ")");
} catch (SAXException e) {
throw new RuntimeException("The osgi repository resolver " + getName()
+ " couldn't be configured: the file " + repoXmlFile + " has incorrect XML (" + e.getMessage()
+ ")");
}
try {
in.close();
} catch (IOException e) {
// don't care
}
} else {
URL url;
try {
url = new URL(repoXmlURL);
} catch (MalformedURLException e) {
throw new RuntimeException("The osgi repository resolver " + getName()
+ " couldn't be configured: repoXmlURL '" + repoXmlURL + "' is not an URL");
}
URL baseUrl;
String basePath = "/";
int i = url.getPath().lastIndexOf("/");
if (i > 0) {
basePath = url.getPath().substring(0, i + 1);
}
try {
baseUrl = new URL(url.getProtocol(), url.getHost(), url.getPort(), basePath);
} catch (MalformedURLException e) {
throw new RuntimeException("The osgi repository resolver " + getName()
+ " couldn't be configured: the base url couldn'd be extracted from the url " + url + " ("
+ e.getMessage() + ")");
}
repository = new RelativeURLRepository(baseUrl);
InputStream in;
try {
in = url.openStream();
} catch (IOException e) {
throw new RuntimeException("The osgi repository resolver " + getName()
+ " couldn't be configured: the file " + repoXmlURL + " couldn't be read (" + e.getMessage()
+ ")");
}
try {
repoDescriptor = OBRXMLParser.parse(in);
} catch (ParseException e) {
throw new RuntimeException("The osgi repository resolver " + getName()
+ " couldn't be configured: the file " + repoXmlURL + " is incorrectly formed ("
+ e.getMessage() + ")");
} catch (IOException e) {
throw new RuntimeException("The osgi repository resolver " + getName()
+ " couldn't be configured: the file " + repoXmlURL + " could not be read (" + e.getMessage()
+ ")");
} catch (SAXException e) {
throw new RuntimeException("The osgi repository resolver " + getName()
+ " couldn't be configured: the file " + repoXmlURL + " has incorrect XML (" + e.getMessage()
+ ")");
}
try {
in.close();
} catch (IOException e) {
// don't care
}
}
}
public Repository getRepository() {
ensureInit();
return repository;
}
private BundleRepo getRepoDescriptor() {
ensureInit();
return repoDescriptor;
}
@Override
public ResolvedModuleRevision getDependency(DependencyDescriptor dd, ResolveData data) throws ParseException {
DefaultModuleDescriptor md = getDependencyMD(dd, data);
if (md == null) {
// not found, so let's return the mrid resolved by a previous resolver
return data.getCurrentResolvedModuleRevision();
}
Artifact mdar = new MDArtifact(md, "MANIFEST", "manifest", "MF");
MetadataArtifactDownloadReport mdardr = new MetadataArtifactDownloadReport(mdar);
mdardr.setDownloadStatus(DownloadStatus.SUCCESSFUL);
return new ResolvedModuleRevision(this, this, md, mdardr);
}
private DefaultModuleDescriptor getDependencyMD(DependencyDescriptor dd, ResolveData data) {
ModuleRevisionId mrid = dd.getDependencyRevisionId();
String osgiAtt = mrid.getAttribute(BundleInfoAdapter.EXTRA_ATTRIBUTE_NAME);
Map<String, Set<BundleCapabilityAndLocation>> bundleCapabilities = getRepoDescriptor()
.getBundleByCapabilities().get(osgiAtt);
if (bundleCapabilities == null) {
Message.verbose("\t Not an OSGi dependency: " + mrid);
return null;
}
String id = mrid.getName();
Set<BundleCapabilityAndLocation> bundleReferences = bundleCapabilities.get(id);
if (bundleReferences == null || bundleReferences.isEmpty()) {
Message.verbose("\t " + id + " not found.");
return null;
}
List<BundleCandidate> ret = new ArrayList<BundleCandidate>();
for (BundleCapabilityAndLocation bundleCapability : bundleReferences) {
BundleInfo bundleInfo = bundleCapability.getBundleInfo();
if (!bundleCapability.getType().equals(BundleInfo.BUNDLE_TYPE)) {
ModuleRevisionId foundMrid = ModuleRevisionId.newInstance("", bundleInfo.getSymbolicName(), bundleInfo
.getVersion().toString(), BundleInfoAdapter.OSGI_BUNDLE);
if (data.getVisitData(foundMrid) != null) {
// already resolved import, no need to go further
DefaultModuleDescriptor md = BundleInfoAdapter.toModuleDescriptor(bundleInfo, profileProvider);
md.setPublicationDate(new Date(0));
return md;
}
}
BundleCandidate candidate = new BundleCandidate();
candidate.bundleInfo = bundleInfo;
candidate.version = bundleCapability.getVersion().toString();
ret.add(candidate);
}
DefaultModuleDescriptor found = selectResource(ret, mrid, data.getDate());
if (found == null) {
Message.debug("\t" + getName() + ": no resource found for " + mrid);
}
return found;
}
private class BundleCandidate implements ArtifactInfo {
BundleInfo bundleInfo;
String version;
public long getLastModified() {
return 0;
}
public String getRevision() {
return version;
}
}
public DefaultModuleDescriptor selectResource(List<BundleCandidate> rress, ModuleRevisionId mrid, Date date) {
VersionMatcher versionMatcher = getSettings().getVersionMatcher();
List<BundleCandidate> founds = new ArrayList<BundleCandidate>();
List<BundleCandidate> sorted = getLatestStrategy().sort(rress.toArray(new BundleCandidate[rress.size()]));
List<String> rejected = new ArrayList<String>();
List<ModuleRevisionId> foundBlacklisted = new ArrayList<ModuleRevisionId>();
IvyContext context = IvyContext.getContext();
for (BundleCandidate rres : sorted) {
if (filterNames(new ArrayList<String>(Collections.singleton(rres.getRevision()))).isEmpty()) {
Message.debug("\t" + getName() + ": filtered by name: " + rres);
continue;
}
if ((date != null && rres.getLastModified() > date.getTime())) {
Message.verbose("\t" + getName() + ": too young: " + rres);
rejected.add(rres.getRevision() + " (" + rres.getLastModified() + ")");
continue;
}
ModuleRevisionId foundMrid = ModuleRevisionId.newInstance(mrid, rres.getRevision());
ResolveData data = context.getResolveData();
if (data != null && data.getReport() != null
&& data.isBlacklisted(data.getReport().getConfiguration(), foundMrid)) {
Message.debug("\t" + getName() + ": blacklisted: " + rres);
rejected.add(rres.getRevision() + " (blacklisted)");
foundBlacklisted.add(foundMrid);
continue;
}
if (!versionMatcher.accept(mrid, foundMrid)) {
Message.debug("\t" + getName() + ": rejected by version matcher: " + rres);
rejected.add(rres.getRevision());
continue;
}
if (versionMatcher.needModuleDescriptor(mrid, foundMrid)) {
throw new IllegalStateException();
} else {
founds.add(rres);
}
}
if (founds.isEmpty() && !rejected.isEmpty()) {
logAttempt(rejected.toString());
}
if (founds.isEmpty() && !foundBlacklisted.isEmpty()) {
// all acceptable versions have been blacklisted, this means that an unsolvable conflict
// has been found
DependencyDescriptor dd = context.getDependencyDescriptor();
IvyNode parentNode = context.getResolveData().getNode(dd.getParentRevisionId());
ConflictManager cm = parentNode.getConflictManager(mrid.getModuleId());
cm.handleAllBlacklistedRevisions(dd, foundBlacklisted);
}
if (founds.isEmpty()) {
return null;
}
BundleCandidate found = founds.get(0);
String osgiAtt = mrid.getAttribute(BundleInfoAdapter.EXTRA_ATTRIBUTE_NAME);
// for non bundle requirement : log the selected bundle
if (!BundleInfo.BUNDLE_TYPE.equals(osgiAtt)) {
// several candidates with different symbolic name : make an warning about the ambiguity
if (founds.size() != 1) {
// several candidates with different symbolic name ?
Map<String, List<BundleCandidate>> matching = new HashMap<String, List<BundleCandidate>>();
for (BundleCandidate c : founds) {
String name = c.bundleInfo.getSymbolicName();
List<BundleCandidate> list = matching.get(name);
if (list == null) {
list = new ArrayList<BundleCandidate>();
matching.put(name, list);
}
list.add(c);
}
if (matching.keySet().size() != 1) {
switch (requirementStrategy) {
case first:
Message.warn("Ambiguity for the '" + osgiAtt + "' requirement " + mrid.getName() + ";version="
+ mrid.getRevision());
for (Entry<String, List<BundleCandidate>> entry : matching.entrySet()) {
Message.warn("\t" + entry.getKey());
for (BundleCandidate c : entry.getValue()) {
Message.warn("\t\t" + c.getRevision() + (found == c ? " (selected)" : ""));
}
}
break;
case noambiguity:
default:
Message.error("Ambiguity for the '" + osgiAtt + "' requirement " + mrid.getName() + ";version="
+ mrid.getRevision());
for (Entry<String, List<BundleCandidate>> entry : matching.entrySet()) {
Message.error("\t" + entry.getKey());
for (BundleCandidate c : entry.getValue()) {
Message.error("\t\t" + c.getRevision() + (found == c ? " (best match)" : ""));
}
}
return null;
}
}
}
Message.info("'" + osgiAtt + "' requirement " + mrid.getName() + ";version=" + mrid.getRevision()
+ " satisfied by " + found.bundleInfo.getSymbolicName() + ";" + found.getRevision());
}
DefaultModuleDescriptor md = BundleInfoAdapter.toModuleDescriptor(found.bundleInfo, profileProvider);
md.setPublicationDate(new Date(found.getLastModified()));
return md;
}
@Override
protected ResolvedResource findArtifactRef(Artifact artifact, Date date) {
ModuleRevisionId mrid = artifact.getModuleRevisionId();
try {
return new ResolvedResource(getRepository().getResource(artifact.getUrl().getFile()), artifact
.getModuleRevisionId().getRevision());
} catch (IOException e) {
throw new RuntimeException(getName() + ": unable to get resource for " + mrid + ": res="
+ artifact.getName() + ": " + e.getMessage(), e);
}
}
protected Collection<String> filterNames(Collection<String> names) {
getSettings().filterIgnore(names);
return names;
}
@Override
protected Collection findNames(Map tokenValues, String token) {
if (BundleInfoAdapter.EXTRA_ATTRIBUTE_NAME.equals(token)) {
return Arrays.asList(new String[] { BundleInfo.BUNDLE_TYPE, BundleInfo.PACKAGE_TYPE,
BundleInfo.SERVICE_TYPE });
}
String osgiAtt = (String) tokenValues.get(BundleInfoAdapter.EXTRA_ATTRIBUTE_NAME);
Map<String, Set<BundleCapabilityAndLocation>> bundleCapabilityMap = getRepoDescriptor()
.getBundleByCapabilities().get(osgiAtt);
if (bundleCapabilityMap == null || bundleCapabilityMap.isEmpty()) {
return Collections.EMPTY_LIST;
}
if (IvyPatternHelper.ORGANISATION_KEY.equals(token)) {
return Collections.singletonList("");
}
if (IvyPatternHelper.MODULE_KEY.equals(token)) {
return bundleCapabilityMap.keySet();
}
if (IvyPatternHelper.REVISION_KEY.equals(token)) {
String name = (String) tokenValues.get(IvyPatternHelper.MODULE_KEY);
List<String> versions = new ArrayList<String>();
Set<BundleCapabilityAndLocation> bundleCapabilities = bundleCapabilityMap.get(name);
if (bundleCapabilities != null) {
for (BundleCapabilityAndLocation bundleCapability : bundleCapabilities) {
versions.add(bundleCapability.getVersion().toString());
}
}
return versions;
}
if (IvyPatternHelper.CONF_KEY.equals(token)) {
String name = (String) tokenValues.get(IvyPatternHelper.MODULE_KEY);
if (name == null) {
return Collections.EMPTY_LIST;
}
if (osgiAtt.equals(BundleInfo.PACKAGE_TYPE)) {
return Collections.singletonList(BundleInfoAdapter.CONF_USE_PREFIX + name);
}
Set<BundleCapabilityAndLocation> bundleCapabilities = bundleCapabilityMap.get(name);
if (bundleCapabilities == null) {
return Collections.EMPTY_LIST;
}
String version = (String) tokenValues.get(IvyPatternHelper.REVISION_KEY);
if (version == null) {
return Collections.EMPTY_LIST;
}
Version v;
try {
v = new Version(version);
} catch (NumberFormatException e) {
return Collections.EMPTY_LIST;
}
BundleCapabilityAndLocation found = null;
for (BundleCapabilityAndLocation bundleCapability : bundleCapabilities) {
if (bundleCapability.getVersion().equals(v)) {
found = bundleCapability;
}
}
if (found == null) {
return Collections.EMPTY_LIST;
}
DefaultModuleDescriptor md = BundleInfoAdapter.toModuleDescriptor(found.getBundleInfo(), profileProvider);
List<String> confs = new ArrayList<String>();
for (Configuration conf : md.getConfigurations()) {
confs.add(conf.getName());
}
return confs;
}
return Collections.EMPTY_LIST;
}
@Override
public Map[] listTokenValues(String[] tokens, Map criteria) {
Set<String> tokenSet = new HashSet<String>(Arrays.asList(tokens));
Set<Map<String, String>> listTokenValues = listTokenValues(tokenSet, criteria);
return listTokenValues.toArray(new Map[listTokenValues.size()]);
}
private Set<Map<String, String>> listTokenValues(Set<String> tokens, Map<String, String> criteria) {
if (tokens.isEmpty()) {
return Collections.<Map<String, String>> singleton(criteria);
}
Set<String> tokenSet = new HashSet<String>(tokens);
Map<String, String> values = new HashMap<String, String>();
tokenSet.remove(BundleInfoAdapter.EXTRA_ATTRIBUTE_NAME);
String osgiAtt = criteria.get(BundleInfoAdapter.EXTRA_ATTRIBUTE_NAME);
if (osgiAtt == null) {
Set<Map<String, String>> tokenValues = new HashSet<Map<String, String>>();
Map<String, String> newCriteria = new HashMap<String, String>(criteria);
newCriteria.put(BundleInfoAdapter.EXTRA_ATTRIBUTE_NAME, BundleInfo.BUNDLE_TYPE);
tokenValues.addAll(listTokenValues(tokenSet, newCriteria));
newCriteria = new HashMap<String, String>(criteria);
newCriteria.put(BundleInfoAdapter.EXTRA_ATTRIBUTE_NAME, BundleInfo.PACKAGE_TYPE);
tokenValues.addAll(listTokenValues(tokenSet, newCriteria));
newCriteria = new HashMap<String, String>(criteria);
newCriteria.put(BundleInfoAdapter.EXTRA_ATTRIBUTE_NAME, BundleInfo.SERVICE_TYPE);
tokenValues.addAll(listTokenValues(tokenSet, newCriteria));
return tokenValues;
}
values.put(BundleInfoAdapter.EXTRA_ATTRIBUTE_NAME, osgiAtt);
Map<String, Set<BundleCapabilityAndLocation>> bundleCapabilityMap = getRepoDescriptor()
.getBundleByCapabilities().get(osgiAtt);
if (bundleCapabilityMap == null || bundleCapabilityMap.isEmpty()) {
return Collections.<Map<String, String>> emptySet();
}
tokenSet.remove(IvyPatternHelper.ORGANISATION_KEY);
String org = criteria.get(IvyPatternHelper.ORGANISATION_KEY);
if (org != null && org.length() != 0) {
return Collections.<Map<String, String>> emptySet();
}
values.put(IvyPatternHelper.ORGANISATION_KEY, "");
tokenSet.remove(IvyPatternHelper.MODULE_KEY);
String module = criteria.get(IvyPatternHelper.MODULE_KEY);
if (module == null) {
Set<String> names = bundleCapabilityMap.keySet();
Set<Map<String, String>> tokenValues = new HashSet<Map<String, String>>();
for (String name : names) {
Map<String, String> newCriteria = new HashMap<String, String>(criteria);
newCriteria.put(IvyPatternHelper.MODULE_KEY, name);
tokenValues.addAll(listTokenValues(tokenSet, newCriteria));
}
return tokenValues;
}
values.put(IvyPatternHelper.MODULE_KEY, module);
tokenSet.remove(IvyPatternHelper.REVISION_KEY);
String rev = criteria.get(IvyPatternHelper.REVISION_KEY);
if (rev == null) {
Set<BundleCapabilityAndLocation> bundleCapabilities = bundleCapabilityMap.get(module);
if (bundleCapabilities == null) {
return Collections.<Map<String, String>> emptySet();
}
Set<Map<String, String>> tokenValues = new HashSet<Map<String, String>>();
for (BundleCapabilityAndLocation capability : bundleCapabilities) {
Map<String, String> newCriteria = new HashMap<String, String>(criteria);
newCriteria.put(IvyPatternHelper.REVISION_KEY, capability.getVersion().toString());
tokenValues.addAll(listTokenValues(tokenSet, newCriteria));
}
return tokenValues;
}
values.put(IvyPatternHelper.REVISION_KEY, rev);
tokenSet.remove(IvyPatternHelper.CONF_KEY);
String conf = criteria.get(IvyPatternHelper.CONF_KEY);
if (conf == null) {
if (osgiAtt.equals(BundleInfo.PACKAGE_TYPE)) {
values.put(IvyPatternHelper.CONF_KEY, BundleInfoAdapter.CONF_USE_PREFIX + module);
return Collections.<Map<String, String>> singleton(values);
}
Set<BundleCapabilityAndLocation> bundleCapabilities = bundleCapabilityMap.get(module);
if (bundleCapabilities == null) {
return Collections.<Map<String, String>> emptySet();
}
Version v;
try {
v = new Version(rev);
} catch (NumberFormatException e) {
return Collections.<Map<String, String>> emptySet();
}
BundleCapabilityAndLocation found = null;
for (BundleCapabilityAndLocation bundleCapability : bundleCapabilities) {
if (bundleCapability.getVersion().equals(v)) {
found = bundleCapability;
}
}
if (found == null) {
return Collections.<Map<String, String>> emptySet();
}
Set<Map<String, String>> tokenValues = new HashSet<Map<String, String>>();
DefaultModuleDescriptor md = BundleInfoAdapter.toModuleDescriptor(found.getBundleInfo(), profileProvider);
for (Configuration c : md.getConfigurations()) {
Map<String, String> newCriteria = new HashMap<String, String>(criteria);
newCriteria.put(IvyPatternHelper.CONF_KEY, c.getName());
tokenValues.add(newCriteria);
}
return tokenValues;
}
values.put(IvyPatternHelper.CONF_KEY, conf);
return Collections.<Map<String, String>> singleton(values);
}
@Override
protected long get(Resource resource, File dest) throws IOException {
Message.verbose("\t" + getName() + ": downloading " + resource.getName());
Message.debug("\t\tto " + dest);
if (dest.getParentFile() != null) {
dest.getParentFile().mkdirs();
}
getRepository().get(resource.getName(), dest);
return dest.length();
}
@Override
protected Resource getResource(String source) throws IOException {
return getRepository().getResource(source);
}
public void publish(Artifact artifact, File src, boolean overwrite) throws IOException {
throw new UnsupportedOperationException();
}
// useless methods that must not be called
public ResolvedResource findIvyFileRef(DependencyDescriptor dd, ResolveData data) {
throw new UnsupportedOperationException();
}
}

View File

@ -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.ivy.osgi.repo;
import java.util.Set;
import java.util.TreeSet;
public class ExecutionEnvironmentProfile {
private Set<String> pkgNames = new TreeSet<String>();
private final String name;
public ExecutionEnvironmentProfile(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void addPkgName(String pkgName) {
if (pkgName != null) {
pkgNames.add(pkgName);
}
}
public Set<String> getPkgNames() {
return pkgNames;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((pkgNames == null) ? 0 : pkgNames.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof ExecutionEnvironmentProfile)) {
return false;
}
ExecutionEnvironmentProfile other = (ExecutionEnvironmentProfile) obj;
if (name == null) {
if (other.name != null) {
return false;
}
} else if (!name.equals(other.name)) {
return false;
}
if (pkgNames == null) {
if (other.pkgNames != null) {
return false;
}
} else if (!pkgNames.equals(other.pkgNames)) {
return false;
}
return true;
}
}

View File

@ -0,0 +1,137 @@
/*
* 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.ivy.osgi.repo;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class FSManifestIterable extends AbstractFSManifestIterable {
/**
* List of directory name that usually contains jars but are not bundles
*/
public static final Set<String> NON_BUNDLE_DIRS = new HashSet<String>(Arrays.asList("source", "sources", "javadoc",
"javadocs", "doc", "docs"));
/**
* Default directory filter that doesn't select .svn directories, neither the directories that match
* {@link #NON_BUNDLE_DIRS}.
*/
public static final FilenameFilter DEFAULT_DIR_FILTER = new FilenameFilter() {
public boolean accept(File dir, String name) {
return !name.equals(".svn") && !NON_BUNDLE_DIRS.contains(name);
}
};
/**
* Default bundle filter that select only .jar files
*/
public static final FilenameFilter DEFAULT_BUNLDE_FILTER = new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.endsWith(".jar");
}
};
private FilenameFilter dirFilter = DEFAULT_DIR_FILTER;
private FilenameFilter bundleFilter = DEFAULT_BUNLDE_FILTER;
private String root;
private final String basePath;
/**
* Default constructor
*
* @param root
* the root directory of the file system to lookup
* @param basePath
* path the found locations should be append to
*/
public FSManifestIterable(File root, String basePath) {
this.basePath = basePath;
this.root = root.getAbsolutePath();
}
public FilenameFilter getDirFilter() {
return dirFilter;
}
public void setDirFilter(FilenameFilter dirFilter) {
this.dirFilter = dirFilter;
}
public FilenameFilter getBundleFilter() {
return bundleFilter;
}
public void setBundleFilter(FilenameFilter bundleFilter) {
this.bundleFilter = bundleFilter;
}
@Override
protected String createBundleLocation(String location) {
return basePath + location;
}
@Override
protected InputStream getInputStream(String f) throws FileNotFoundException {
return new FileInputStream(new File(root, f));
}
@Override
protected List<String> listBundleFiles(String dir) {
return fileArray2pathList(new File(root, dir).listFiles(new FileFilter() {
public boolean accept(File f) {
if (!f.isFile()) {
return false;
}
return bundleFilter.accept(f.getParentFile(), f.getName());
}
}));
}
private List<String> fileArray2pathList(File[] files) {
ArrayList<String> list = new ArrayList<String>(files.length);
for (int i = 0; i < files.length; i++) {
list.add(files[i].getAbsolutePath().substring(root.length() + 1));
}
return list;
}
@Override
protected List<String> listDirs(String dir) {
return fileArray2pathList(new File(root, dir).listFiles(new FileFilter() {
public boolean accept(File f) {
if (!f.isDirectory()) {
return false;
}
return dirFilter == null || dirFilter.accept(f.getParentFile(), f.getName());
}
}));
}
}

View File

@ -0,0 +1,44 @@
/*
* 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.ivy.osgi.repo;
import java.util.jar.Manifest;
public class ManifestAndLocation {
private final Manifest manifest;
/**
* location of the jar relative to the repository URL
*/
private final String location;
public ManifestAndLocation(Manifest manifest, String location) {
this.manifest = manifest;
this.location = location;
}
public String getLocation() {
return location;
}
public Manifest getManifest() {
return manifest;
}
}

View File

@ -0,0 +1,70 @@
/*
* 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.ivy.osgi.repo;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.text.ParseException;
import java.util.jar.Manifest;
import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
import org.apache.ivy.osgi.core.BundleInfo;
import org.apache.ivy.osgi.core.ManifestParser;
import org.apache.ivy.osgi.repo.osgi.ExecutionEnvironmentProfileProvider;
import org.apache.ivy.plugins.parser.AbstractModuleDescriptorParser;
import org.apache.ivy.plugins.parser.ParserSettings;
import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorWriter;
import org.apache.ivy.plugins.repository.Resource;
public class ManifestMDParser extends AbstractModuleDescriptorParser {
private ExecutionEnvironmentProfileProvider profileProvider;
public void add(ExecutionEnvironmentProfileProvider pp) {
this.profileProvider = pp;
}
public boolean accept(Resource res) {
if (res == null || res.getName() == null || res.getName().trim().equals("")) {
return false;
}
return res.getName().toUpperCase().endsWith("MANIFEST.MF");
}
public ModuleDescriptor parseDescriptor(ParserSettings ivySettings, URL descriptorURL, Resource res,
boolean validate) throws ParseException, IOException {
Manifest m = new Manifest(res.openStream());
BundleInfo bundleInfo = ManifestParser.parseManifest(m);
return BundleInfoAdapter.toModuleDescriptor(bundleInfo, profileProvider);
}
public void toIvyFile(InputStream is, Resource res, File destFile, ModuleDescriptor md) throws ParseException,
IOException {
try {
XmlModuleDescriptorWriter.write(md, destFile);
} finally {
if (is != null) {
is.close();
}
}
}
}

View File

@ -0,0 +1,65 @@
/*
* 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.ivy.osgi.repo;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import org.apache.ivy.plugins.repository.Resource;
import org.apache.ivy.plugins.repository.url.URLRepository;
import org.apache.ivy.plugins.repository.url.URLResource;
public class RelativeURLRepository extends URLRepository {
private final URL baseUrl;
public RelativeURLRepository() {
super();
baseUrl = null;
}
public RelativeURLRepository(URL baseUrl) {
super();
this.baseUrl = baseUrl;
}
private Map<String, Resource> resourcesCache = new HashMap<String, Resource>();
@Override
public Resource getResource(String source) throws IOException {
source = encode(source);
Resource res = resourcesCache.get(source);
if (res == null) {
if (baseUrl == null) {
res = new URLResource(new URL(source));
} else {
res = new URLResource(new URL(baseUrl + source));
}
resourcesCache.put(source, res);
}
return res;
}
private static String encode(String source) {
// TODO: add some more URL encodings here
return source.trim().replaceAll(" ", "%20");
}
}

View File

@ -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.ivy.osgi.repo;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.apache.ivy.plugins.repository.Repository;
import org.apache.ivy.plugins.resolver.util.ResolverHelper;
public class RepositoryManifestIterable extends AbstractFSManifestIterable {
private final Repository repo;
/**
* Default constructor
*
* @param root
* the root directory of the file system to lookup
*/
public RepositoryManifestIterable(Repository repo) {
this.repo = repo;
}
@Override
protected InputStream getInputStream(String f) throws IOException {
return repo.getResource(f).openStream();
}
@Override
protected List<String> listBundleFiles(String dir) throws IOException {
return asList(ResolverHelper.listAll(repo, dir));
}
@Override
protected List<String> listDirs(String dir) throws IOException {
return asList(ResolverHelper.listAll(repo, dir));
}
private List<String> asList(String[] array) {
return array == null ? Collections.<String> emptyList() : Arrays.<String> asList(array);
}
}

View File

@ -0,0 +1,201 @@
/*
* 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.ivy.osgi.repo;
import java.io.IOException;
import java.text.ParseException;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.jar.JarInputStream;
import java.util.jar.Manifest;
import org.apache.ivy.core.event.EventManager;
import org.apache.ivy.core.module.descriptor.Artifact;
import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor;
import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.core.resolve.ResolveData;
import org.apache.ivy.core.resolve.ResolveEngine;
import org.apache.ivy.core.resolve.ResolveOptions;
import org.apache.ivy.core.resolve.ResolvedModuleRevision;
import org.apache.ivy.core.search.ModuleEntry;
import org.apache.ivy.core.search.OrganisationEntry;
import org.apache.ivy.core.search.RevisionEntry;
import org.apache.ivy.core.settings.IvySettings;
import org.apache.ivy.core.sort.SortEngine;
import org.apache.ivy.plugins.resolver.BasicResolver;
import org.apache.ivy.plugins.resolver.BasicResolverWrapper;
import org.apache.ivy.plugins.resolver.util.ResolvedResource;
import org.apache.ivy.util.Message;
public class ResolverManifestIterable implements Iterable<ManifestAndLocation> {
// We should support the interface DependencyResolver, but the API is not convenient to get references to artifact
private final BasicResolverWrapper resolver;
public ResolverManifestIterable(BasicResolver resolver) {
this.resolver = new BasicResolverWrapper(resolver);
}
public Iterator<ManifestAndLocation> iterator() {
return new ResolverManifestIterator();
}
class ResolverManifestIterator implements Iterator<ManifestAndLocation> {
private OrganisationEntry[] organisations;
private int indexOrganisation = 0;
private OrganisationEntry organisation;
private ModuleEntry[] modules;
private int indexModule = -1;
private ModuleEntry module;
private ManifestAndLocation next = null;
private RevisionEntry[] revisions;
private int indexRevision;
private RevisionEntry revision;
private Artifact[] artifacts;
private int indexArtifact;
private Artifact artifact;
private ModuleRevisionId mrid;
private ResolveData data;
public ResolverManifestIterator() {
organisations = resolver.listOrganisations();
IvySettings settings = new IvySettings();
ResolveEngine engine = new ResolveEngine(settings, new EventManager(), new SortEngine(settings));
data = new ResolveData(engine, new ResolveOptions());
}
public boolean hasNext() {
while (next == null) {
if (organisation == null) {
if (indexOrganisation >= organisations.length) {
return false;
}
organisation = organisations[indexOrganisation++];
modules = resolver.listModules(organisation);
indexModule = 0;
module = null;
}
if (module == null) {
if (indexModule >= modules.length) {
organisation = null;
continue;
}
module = modules[indexModule++];
revisions = resolver.listRevisions(module);
indexRevision = 0;
revision = null;
}
if (revision == null) {
if (indexRevision >= revisions.length) {
module = null;
continue;
}
revision = revisions[indexRevision++];
mrid = ModuleRevisionId.newInstance(organisation.getOrganisation(), module.getModule(), revision
.getRevision());
DefaultDependencyDescriptor dd = new DefaultDependencyDescriptor(mrid, false);
ResolvedModuleRevision dependency;
try {
dependency = resolver.getDependency(dd, data);
} catch (ParseException e) {
Message.error("Error while resolving " + mrid + " : " + e.getMessage());
revision = null;
continue;
}
if (dependency == null) {
revision = null;
continue;
}
ModuleDescriptor md = dependency.getDescriptor();
mrid = md.getModuleRevisionId();
artifacts = md.getAllArtifacts();
indexArtifact = 0;
artifact = null;
}
if (artifact == null) {
if (indexArtifact >= artifacts.length) {
revision = null;
continue;
}
artifact = artifacts[indexArtifact++];
}
ResolvedResource resource = resolver.findArtifactRef(artifact, null);
if (resource == null) {
artifact = null;
continue;
}
JarInputStream in;
try {
in = new JarInputStream(resource.getResource().openStream());
} catch (IOException e) {
Message.warn("Unreadable jar " + resource.getResource().getName() + " (" + e.getMessage() + ")");
artifact = null;
continue;
}
Manifest manifest;
try {
manifest = in.getManifest();
} finally {
try {
in.close();
} catch (IOException e) {
// don't care
}
}
if (manifest == null) {
Message.debug("No manifest on " + artifact);
} else {
String location = BundleInfoAdapter.encodeIvyLocation(artifact);
next = new ManifestAndLocation(manifest, location);
}
artifact = null;
}
return true;
}
public ManifestAndLocation next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
ManifestAndLocation manifest = next;
next = null;
return manifest;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
}

View File

@ -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.ivy.osgi.repo.osgi;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.apache.ivy.osgi.repo.ExecutionEnvironmentProfile;
import org.apache.ivy.util.Message;
/**
* Load profiles provided by the <tt>org.eclipse.osgi</tt> bundle.
*/
public class ExecutionEnvironmentProfileProvider {
private static final String PROFILE_NAME = "osgi.java.profile.name";
private static final String SYSTEM_PACKAGES = "org.osgi.framework.system.packages";
private static final String PROFILE_LIST_FILE = "profile.list";
private static final String PACKAGE_PREFIX = "org/apache/ivy/osgi/repo/osgi/";
private static final String PROFILE_LIST = "java.profiles";
private Map<String, ExecutionEnvironmentProfile> profileList;
// private static final String BOOT_DELEGATION = "org.osgi.framework.bootdelegation";
// private static final String ENVIRONMENT = "org.osgi.framework.executionenvironment";
public ExecutionEnvironmentProfileProvider() throws IOException {
profileList = loadDefaultProfileList();
}
public ExecutionEnvironmentProfile getProfile(String profile) {
return profileList.get(profile);
}
public static Map<String, ExecutionEnvironmentProfile> loadDefaultProfileList() throws IOException {
ClassLoader loader = ExecutionEnvironmentProfileProvider.class.getClassLoader();
InputStream profileListFile = loader.getResourceAsStream(PACKAGE_PREFIX + PROFILE_LIST_FILE);
if (profileListFile == null) {
throw new FileNotFoundException(PACKAGE_PREFIX + PROFILE_LIST_FILE + " not found in the classpath");
}
Properties props = new Properties();
props.load(profileListFile);
String[] profileList = props.getProperty(PROFILE_LIST).split(",");
Message.debug("Loading profiles " + profileList);
Map<String, ExecutionEnvironmentProfile> map = new HashMap<String, ExecutionEnvironmentProfile>();
for (String profileFile : profileList) {
String p = profileFile.trim();
if (p.length() != 0) {
ExecutionEnvironmentProfile profile = load(loader.getResourceAsStream(PACKAGE_PREFIX + p));
if (profile != null) {
Message.verbose("Execution environment profile " + profile.getName() + " loaded");
map.put(profile.getName(), profile);
} else {
Message.warn("Unable to load the environement profile " + PACKAGE_PREFIX + p);
}
}
}
return map;
}
public static ExecutionEnvironmentProfile load(File f) throws IOException {
return load(new FileInputStream(f));
}
public static ExecutionEnvironmentProfile load(InputStream in) throws IOException {
Properties props = new Properties();
props.load(in);
return load(props);
}
public static ExecutionEnvironmentProfile load(Properties properties) {
ExecutionEnvironmentProfile profile = new ExecutionEnvironmentProfile(properties.getProperty(PROFILE_NAME));
String packagesList = properties.getProperty(SYSTEM_PACKAGES);
if (packagesList == null) {
Message.warn("The profile " + profile.getName() + " doesn't have any system package definition");
return null;
}
String[] packages = packagesList.split(",");
for (String pkg : packages) {
profile.addPkgName(pkg.trim());
}
return profile;
}
}

View File

@ -0,0 +1,80 @@
/*
* 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.ivy.osgi.util;
import java.util.Comparator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ArtifactTokens {
public static final Comparator<ArtifactTokens> ORDER_BY_VERSION_ASC = new OrderByVersion(true);
public static final Comparator<ArtifactTokens> ORDER_BY_VERSION_DESC = new OrderByVersion(false);
protected static final Pattern ARTIFACT_TOKEN_REGEX = Pattern.compile("(.*/)?([\\w\\.]+)[\\-_](\\d*\\.\\d*\\.\\d*)[\\.]?([\\w\\-]+)?");
public final String prefix;
public final String module;
public final Version version;
public final boolean isJar;
public ArtifactTokens(String artifactStr) {
isJar = artifactStr.endsWith(".jar");
artifactStr = (isJar ? artifactStr.substring(0, artifactStr.length() - 4) : artifactStr);
final Matcher matcher = ARTIFACT_TOKEN_REGEX.matcher(artifactStr);
if (matcher.matches()) {
prefix = matcher.group(1);
module = matcher.group(2);
version = new Version(matcher.group(3), matcher.group(4));
} else {
prefix = null;
module = null;
version = null;
}
}
@Override
public String toString() {
return (prefix != null ? prefix : "") + module + "-" + version + (isJar ? ".jar" : "");
}
public String toDetailString() {
return String.format("prefix=%s, module=%s, version=%s, isJar=%s", prefix, module, version, isJar);
}
public boolean isValid() {
return (prefix != null) && (module != null) && (version != null);
}
private static class OrderByVersion implements Comparator<ArtifactTokens> {
private final boolean ascending;
public OrderByVersion(boolean ascending) {
this.ascending = ascending;
}
public int compare(ArtifactTokens a, ArtifactTokens b) {
if (!a.module.equalsIgnoreCase(b.module)) {
throw new IllegalArgumentException("Cannot order different modules by version. A=" + a + ", B=" + b);
}
final int val = a.version.compareTo(b.version);
return (ascending ? val : -val);
}
}
}

View File

@ -0,0 +1,423 @@
/*
* 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.ivy.osgi.util;
import java.util.HashMap;
import java.util.Map;
import org.apache.ivy.util.cli.ParseException;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.DTDHandler;
import org.xml.sax.ErrorHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
public class DelegetingHandler<P extends DelegetingHandler<?>> implements DTDHandler, ContentHandler, ErrorHandler {
private DelegetingHandler<?> delegate = null;
private P parent;
private final Map<String, DelegetingHandler<?>> mapping = new HashMap<String, DelegetingHandler<?>>();
private final String tagName;
private boolean started = false;
private boolean skip = false;
private StringBuilder charBuffer = new StringBuilder();
private boolean bufferingChar = false;
private Locator locator;
public DelegetingHandler(String name, P parent) {
this.tagName = name;
this.parent = parent;
if (parent != null) {
parent.mapping.put(name, this);
}
charBuffer.setLength(0);
}
public String getName() {
return tagName;
}
public P getParent() {
return parent;
}
public void setBufferingChar(boolean bufferingChar) {
this.bufferingChar = bufferingChar;
}
public boolean isBufferingChar() {
return bufferingChar;
}
public String getBufferedChars() {
return charBuffer.toString();
}
public void setDocumentLocator(Locator locator) {
this.locator = locator;
for (DelegetingHandler<?> subHandler : mapping.values()) {
subHandler.setDocumentLocator(locator);
}
}
public Locator getLocator() {
return locator;
}
public void skip() {
skip = true;
for (DelegetingHandler<?> subHandler : mapping.values()) {
subHandler.reset();
}
}
protected void reset() {
parent.delegate = null;
skip = false;
started = false;
charBuffer.setLength(0);
for (DelegetingHandler<?> subHandler : mapping.values()) {
subHandler.reset();
}
}
public final void startDocument() throws SAXException {
if (skip) {
return;
}
if (delegate != null) {
delegate.startDocument();
} else {
doStartDocument();
}
}
/**
* @throws SAXException
*/
protected void doStartDocument() throws SAXException {
// by default do nothing
}
public final void endDocument() throws SAXException {
if (skip) {
return;
}
if (delegate != null) {
delegate.endDocument();
} else {
doEndDocument();
}
}
/**
* @throws SAXException
*/
protected void doEndDocument() throws SAXException {
// by default do nothing
}
public final void startElement(String uri, String localName, String n, Attributes atts) throws SAXException {
if (delegate != null) {
delegate.startElement(uri, localName, n, atts);
} else {
if (!started) {
if (localName.equals(tagName)) {
handleAttributes(atts);
started = true;
} else if (parent == null) {
// we are at the root and the saxed element doesn't match
throw new SAXException("The root element of the parsed document '" + localName
+ "' didn't matched the expected one: '" + tagName + "'");
}
} else {
if (skip) {
return;
}
if (mapping != null) {
DelegetingHandler<?> delegetingHandler = mapping.get(localName);
if (delegetingHandler != null) {
delegate = delegetingHandler;
}
}
if (delegate != null) {
delegate.startElement(uri, localName, n, atts);
} else {
doStartElement(uri, localName, localName, atts);
}
}
}
}
/**
* Called when the expected node is achieved
*
* @param atts
* the xml attributes attached to the expected node
* @exception SAXException
* in case the parsing should be completely stopped
*/
protected void handleAttributes(Attributes atts) throws SAXException {
// nothing to do by default
}
/**
* @throws SAXException
*/
protected void doStartElement(String uri, String localName, String name, Attributes atts) throws SAXException {
// by default do nothing
}
public final void endElement(String uri, String localName, String n) throws SAXException {
if (delegate != null) {
delegate.endElement(uri, localName, n);
} else {
if (!skip) {
doEndElement(uri, localName, n);
}
if (parent != null && tagName.equals(localName)) {
reset();
}
}
}
/**
* @throws SAXException
*/
protected void doEndElement(String uri, String localName, String name) throws SAXException {
// by default do nothing
}
public final void characters(char[] ch, int start, int length) throws SAXException {
if (skip) {
return;
}
if (delegate != null) {
delegate.characters(ch, start, length);
} else {
doCharacters(ch, start, length);
}
}
/**
* @throws SAXException
*/
protected void doCharacters(char[] ch, int start, int length) throws SAXException {
if (bufferingChar) {
charBuffer.append(ch, start, length);
}
}
public final void startPrefixMapping(String prefix, String uri) throws SAXException {
if (skip) {
return;
}
if (delegate != null) {
delegate.startPrefixMapping(prefix, uri);
} else {
doStartPrefixMapping(prefix, uri);
}
}
/**
* @throws SAXException
*/
protected void doStartPrefixMapping(String prefix, String uri) throws SAXException {
// by default do nothing
}
public final void endPrefixMapping(String prefix) throws SAXException {
if (skip) {
return;
}
if (delegate != null) {
delegate.endPrefixMapping(prefix);
} else {
doEndPrefixMapping(prefix);
}
}
/**
* @throws SAXException
*/
protected void doEndPrefixMapping(String prefix) throws SAXException {
// by default do nothing
}
public final void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
if (skip) {
return;
}
if (delegate != null) {
delegate.ignorableWhitespace(ch, start, length);
} else {
doIgnorableWhitespace(ch, start, length);
}
}
/**
* @throws SAXException
*/
protected void doIgnorableWhitespace(char[] ch, int start, int length) throws SAXException {
// by default do nothing
}
public final void notationDecl(String name, String publicId, String systemId) throws SAXException {
if (skip) {
return;
}
if (delegate != null) {
delegate.notationDecl(name, publicId, systemId);
} else {
doNotationDecl(name, publicId, systemId);
}
}
/**
* @throws SAXException
*/
protected void doNotationDecl(String name, String publicId, String systemId) throws SAXException {
// by default do nothing
}
public final void processingInstruction(String target, String data) throws SAXException {
if (skip) {
return;
}
if (delegate != null) {
delegate.processingInstruction(target, data);
} else {
doProcessingInstruction(target, data);
}
}
/**
* @throws SAXException
*/
protected void doProcessingInstruction(String target, String data) throws SAXException {
// by default do nothing
}
public final void skippedEntity(String name) throws SAXException {
if (skip) {
return;
}
if (delegate != null) {
delegate.skippedEntity(name);
} else {
doSkippedEntity(name);
}
}
/**
* @throws SAXException
*/
protected void doSkippedEntity(String name) throws SAXException {
// by default do nothing
}
/**
* @throws SAXException
*/
public final void unparsedEntityDecl(String name, String publicId, String systemId, String notationName)
throws SAXException {
if (skip) {
return;
}
if (delegate != null) {
delegate.unparsedEntityDecl(name, publicId, systemId, notationName);
} else {
doUnparsedEntityDecl(name, publicId, systemId, notationName);
}
}
/**
* @throws SAXException
*/
protected void doUnparsedEntityDecl(String name, String publicId, String systemId, String notationName)
throws SAXException {
// by default do nothing
}
// ERROR HANDLING
public final void warning(SAXParseException exception) throws SAXException {
if (skip) {
return;
}
if (delegate != null) {
delegate.warning(exception);
} else {
doWarning(exception);
}
}
/**
* @throws SAXException
*/
protected void doWarning(SAXParseException exception) throws SAXException {
// by default do nothing
}
public final void error(SAXParseException exception) throws SAXException {
if (skip) {
return;
}
if (delegate != null) {
delegate.error(exception);
} else {
doError(exception);
}
}
/**
* @throws SAXException
*/
protected void doError(SAXParseException exception) throws SAXException {
// by default do nothing
}
public final void fatalError(SAXParseException exception) throws SAXException {
if (skip) {
return;
}
if (delegate != null) {
delegate.fatalError(exception);
} else {
doFatalError(exception);
}
}
/**
* @throws SAXException
*/
protected void doFatalError(SAXParseException exception) throws SAXException {
// by default do nothing
}
}

View File

@ -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.ivy.osgi.util;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.Set;
/**
* Provides a bundle name conversion utility.
*
* @author alex@radeski.net
*/
public class NameUtil {
private static final NameUtil instance = new NameUtil();
public static NameUtil instance() {
return instance;
}
private final Set<String> tlds = new HashSet<String>();
private NameUtil() {
final InputStream inputStream = getClass().getClassLoader().getResourceAsStream("orgs.list");
if (inputStream == null) {
throw new IllegalStateException("Unable to find required file in classpath: orgs.list");
}
final BufferedReader bis = new BufferedReader(new InputStreamReader(inputStream));
try {
String line = null;
while ((line = bis.readLine()) != null) {
line = line.trim();
if (line.equals("") || line.startsWith("#")) {
continue;
}
tlds.add(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public OrgAndName asOrgAndName(String qname) {
final String[] tokens = qname.split("\\.");
if ((tokens == null) || (tokens.length == 0)) {
throw new IllegalStateException("Qualified name is empty or invalid: " + qname);
}
String org = null;
String name = null;
if (tlds.contains(tokens[0])) {
org = append(tokens, 0, 1);
name = append(tokens, 2, tokens.length);
} else if (tokens.length == 1) {
org = tokens[0];
name = tokens[0];
} else if (tokens.length >= 2) {
org = tokens[0];
name = append(tokens, 1, tokens.length);
}
if (org == null || name == null) {
throw new IllegalStateException("Null org/name: org=" + org + ", name=" + name + ", qname=" + qname);
}
return new OrgAndName(org, name);
}
private String append(String[] strs, int start, int end) {
final StringBuffer sbuf = new StringBuffer();
boolean dot = false;
for (int i = start; i <= end && i < strs.length; i++) {
if (dot) {
sbuf.append('.');
}
sbuf.append(strs[i]);
dot = true;
}
return sbuf.toString();
}
public static class OrgAndName {
public final String org;
public final String name;
private OrgAndName(String org, String name) {
this.org = org;
this.name = name;
}
}
}

View File

@ -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.ivy.osgi.util;
import java.util.ArrayList;
import java.util.List;
/**
* @author jerome@benois.fr
*/
public class ParseUtil {
/**
* Parses delimited string and returns an array containing the tokens. This parser obeys quotes, so the delimiter
* character will be ignored if it is inside of a quote. This method assumes that the quote character is not
* included in the set of delimiter characters.
*
* @param value the delimited string to parse.
* @param delim the characters delimiting the tokens.
* @return an array of string tokens or null if there were no tokens.
*/
// method largely inspired by Apache Felix 1.0.4 ManifestParser method
@SuppressWarnings("unchecked")
public static String[] parseDelimitedString(String value, String delim) {
if (value == null) {
value = "";
}
final List list = new ArrayList();
final int CHAR = 1;
final int DELIMITER = 2;
final int STARTQUOTE = 4;
final int ENDQUOTE = 8;
final StringBuffer sb = new StringBuffer();
int expecting = (CHAR | DELIMITER | STARTQUOTE);
for (int i = 0; i < value.length(); i++) {
final char c = value.charAt(i);
final boolean isDelimiter = (delim.indexOf(c) >= 0);
final boolean isQuote = (c == '"');
if (isDelimiter && ((expecting & DELIMITER) > 0)) {
list.add(sb.toString().trim());
sb.delete(0, sb.length());
expecting = (CHAR | DELIMITER | STARTQUOTE);
} else if (isQuote && ((expecting & STARTQUOTE) > 0)) {
sb.append(c);
expecting = CHAR | ENDQUOTE;
} else if (isQuote && ((expecting & ENDQUOTE) > 0)) {
sb.append(c);
expecting = (CHAR | STARTQUOTE | DELIMITER);
} else if ((expecting & CHAR) > 0) {
sb.append(c);
} else {
throw new IllegalArgumentException("Invalid delimited string: " + value);
}
}
if (sb.length() > 0) {
list.add(sb.toString().trim());
}
return (String[]) list.toArray(new String[list.size()]);
}
}

View File

@ -0,0 +1,144 @@
/*
* 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.ivy.osgi.util;
import static java.lang.Integer.parseInt;
/**
* Provides OSGi version support.
*/
public class Version implements Comparable<Version> {
private final int major;
private final int minor;
private final int patch;
private final String qualifier;
public Version(String versionStr, String qualifier) throws NumberFormatException {
this(versionStr + "." + (qualifier != null ? qualifier : ""));
}
public Version(String versionStr) throws NumberFormatException {
final String[] tmp = versionStr.split("[\\.]");
major = parseInt(tmp[0]);
minor = tmp.length >= 2 ? parseInt(tmp[1]) : 0;
patch = tmp.length >= 3 ? parseInt(tmp[2]) : 0;
qualifier = tmp.length == 4 ? tmp[3] : null;
}
public Version(int major, int minor, int patch, String qualifier) {
this.major = major;
this.minor = minor;
this.patch = patch;
this.qualifier = qualifier;
}
@Override
public String toString() {
return numbersAsString() + (qualifier == null ? "" : "." + qualifier);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + major;
result = prime * result + minor;
result = prime * result + patch;
result = prime * result + ((qualifier == null) ? 0 : qualifier.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof Version)) {
return false;
}
Version other = (Version) obj;
if (major != other.major) {
return false;
}
if (minor != other.minor) {
return false;
}
if (patch != other.patch) {
return false;
}
if (qualifier == null) {
if (other.qualifier != null) {
return false;
}
} else if (!qualifier.equals(other.qualifier)) {
return false;
}
return true;
}
public String numbersAsString() {
return major + "." + minor + "." + patch;
}
public Version withNudgedPatch() {
return new Version(major, minor, patch + 1, null);
}
public Version withoutQualifier() {
return new Version(major, minor, patch, null);
}
public String qualifier() {
return qualifier == null ? "" : qualifier;
}
public int compareUnqualified(Version other) {
int diff = major - other.major;
if (diff != 0) {
return diff;
}
diff = minor - other.minor;
if (diff != 0) {
return diff;
}
diff = patch - other.patch;
if (diff != 0) {
return diff;
}
return 0;
}
public int compareTo(Version other) {
int diff = compareUnqualified(other);
if (diff != 0) {
return diff;
}
if (qualifier == null) {
return other.qualifier != null ? -1 : 0;
}
if (other.qualifier == null) {
return 1;
}
return qualifier.compareTo(other.qualifier);
}
}

View File

@ -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.ivy.osgi.util;
import java.util.Comparator;
public class VersionComparator implements Comparator<Version> {
public static final Comparator<Version> ASCENDING = new VersionComparator(false);
public static final Comparator<Version> DESCENDING = new VersionComparator(true);
public final boolean reverse;
private VersionComparator(boolean reverse) {
this.reverse = reverse;
}
public int compare(Version objA, Version objB) {
final int val = objA.compareTo(objB);
return (reverse ? -val : val);
}
}

View File

@ -0,0 +1,362 @@
/*
* 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.ivy.osgi.util;
import java.text.ParseException;
/**
* Provides version range support.
*/
public class VersionRange {
private boolean startExclusive;
private Version startVersion;
private boolean endExclusive;
private Version endVersion;
public VersionRange(String versionStr) throws ParseException {
if (versionStr == null || versionStr.length() == 0) {
startExclusive = false;
startVersion = new Version(0, 0, 0, null);
endExclusive = true;
endVersion = null;
} else {
new VersionRangeParser(versionStr).parse();
}
}
class VersionRangeParser {
/**
* value to parse
*/
private final String version;
/**
* the length of the source
*/
private int length;
/**
* position in the source
*/
private int pos = 0;
/**
* last read character
*/
private char c;
/**
* Default constructor
*
* @param header
* the header to parse
*/
VersionRangeParser(String version) {
this.version = version;
this.length = version.length();
}
/**
* Do the parsing
*
* @throws ParseException
*/
void parse() throws ParseException {
boolean range = parseStart();
startVersion = parseVersion();
if (startVersion == null) {
throw new ParseException("Expecting a number", pos);
}
if (parseVersionSeparator()) {
endVersion = parseVersion();
parseEnd();
} else if (range) {
throw new ParseException("Expecting ,", pos);
} else {
// simple number
endVersion = null;
startExclusive = false;
endExclusive = false;
}
}
private char readNext() {
if (pos == length) {
c = '\0';
} else {
c = version.charAt(pos++);
}
return c;
}
private void unread() {
if (pos > 0) {
pos--;
}
}
private boolean parseStart() {
skipWhiteSpace();
switch (readNext()) {
case '[':
startExclusive = false;
return true;
case '(':
startExclusive = true;
return true;
default:
unread();
return false;
}
}
private void skipWhiteSpace() {
do {
switch (readNext()) {
case ' ':
continue;
default:
unread();
return;
}
} while (pos < length);
}
private Version parseVersion() {
Integer major = parseNumber();
if (major == null) {
return null;
}
Integer minor = 0;
Integer patch = 0;
String qualififer = null;
if (parseNumberSeparator()) {
minor = parseNumber();
if (minor == null) {
minor = 0;
} else if (parseNumberSeparator()) {
patch = parseNumber();
if (patch == null) {
patch = 0;
} else if (parseNumberSeparator()) {
qualififer = parseQualifier();
}
}
}
return new Version(major, minor, patch, qualififer);
}
private Integer parseNumber() {
skipWhiteSpace();
Integer n = null;
do {
switch (readNext()) {
case '\0':
return n;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
n = (n == null ? 0 : n * 10) + c - '0';
break;
default:
unread();
return n;
}
} while (pos < length);
return n;
}
private boolean parseNumberSeparator() {
switch (readNext()) {
case '.':
return true;
default:
unread();
return false;
}
}
private boolean parseVersionSeparator() {
skipWhiteSpace();
switch (readNext()) {
case ',':
return true;
default:
unread();
return false;
}
}
private String parseQualifier() {
StringBuilder q = new StringBuilder();
do {
readNext();
if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' || c == '-' || c == '_') {
q.append(c);
} else {
unread();
break;
}
} while (pos < length);
if (q.length() == 0) {
return null;
}
return q.toString();
}
private void parseEnd() throws ParseException {
skipWhiteSpace();
switch (readNext()) {
case ']':
endExclusive = false;
break;
case ')':
endExclusive = true;
break;
default:
unread();
throw new ParseException("Expexting ] or )", pos);
}
}
}
public VersionRange(boolean startExclusive, Version startVersion, boolean endExclusive, Version endVersion) {
this.startExclusive = startExclusive;
this.startVersion = startVersion;
this.endExclusive = endExclusive;
this.endVersion = endVersion;
}
@Override
public String toString() {
return (startExclusive ? "(" : "[") + startVersion + "," + (endVersion == null ? "" : endVersion)
+ (endExclusive ? ")" : "]");
}
public String toIvyRevision() {
StringBuilder buffer = new StringBuilder();
buffer.append(startExclusive ? "(" : "[");
buffer.append(startVersion);
if (endVersion == null) {
buffer.append(",)");
} else if (!endExclusive || startVersion.equals(endVersion)) {
buffer.append(",");
buffer.append(endVersion.withNudgedPatch());
buffer.append(")");
} else {
buffer.append(",");
buffer.append(endVersion);
buffer.append(")");
}
return buffer.toString();
}
public boolean isEndExclusive() {
return this.endExclusive;
}
public Version getEndVersion() {
return this.endVersion;
}
public boolean isStartExclusive() {
return this.startExclusive;
}
public Version getStartVersion() {
return this.startVersion;
}
public boolean isClosedRange() {
return startVersion.equals(endVersion);
}
public boolean contains(String versionStr) {
return contains(new Version(versionStr));
}
public boolean contains(Version version) {
if (startExclusive ? version.compareUnqualified(startVersion) <= 0
: version.compareUnqualified(startVersion) < 0) {
return false;
}
if (endVersion == null) {
return true;
}
if (endExclusive ? version.compareUnqualified(endVersion) >= 0 : version.compareUnqualified(endVersion) > 0) {
return false;
}
return true;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (endExclusive ? 1231 : 1237);
result = prime * result + ((endVersion == null) ? 0 : endVersion.hashCode());
result = prime * result + (startExclusive ? 1231 : 1237);
result = prime * result + ((startVersion == null) ? 0 : startVersion.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof VersionRange)) {
return false;
}
VersionRange other = (VersionRange) obj;
if (endExclusive != other.endExclusive) {
return false;
}
if (endVersion == null) {
if (other.endVersion != null) {
return false;
}
} else if (!endVersion.equals(other.endVersion)) {
return false;
}
if (startExclusive != other.startExclusive) {
return false;
}
if (startVersion == null) {
if (other.startVersion != null) {
return false;
}
} else if (!startVersion.equals(other.startVersion)) {
return false;
}
return true;
}
}

View File

@ -0,0 +1,64 @@
/*
* 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.ivy.osgi.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* Class derived from code posted here: http://forums.sun.com/thread.jspa?messageID=2160923
*/
public class ZipUtil {
public static void zip(File sourceDir, OutputStream targetStream) throws IOException {
if (!sourceDir.isFile() && !sourceDir.isDirectory()) {
return;
}
final ZipOutputStream cpZipOutputStream = new ZipOutputStream(targetStream);
cpZipOutputStream.setLevel(9);
zipFiles(sourceDir, sourceDir, cpZipOutputStream);
cpZipOutputStream.finish();
cpZipOutputStream.close();
}
private static void zipFiles(File rootDir, File currDir, ZipOutputStream zos) throws IOException {
if (currDir.isDirectory()) {
final File[] files = currDir.listFiles();
for (int i = 0; i < files.length; i++) {
zipFiles(rootDir, files[i], zos);
}
} else {
final String strAbsPath = currDir.getPath();
final String strZipEntryName = strAbsPath.substring(rootDir.getPath().length() + 1, strAbsPath.length());
final byte[] b = new byte[(int) (currDir.length())];
final FileInputStream fis = new FileInputStream(currDir);
fis.read(b);
fis.close();
final ZipEntry entry = new ZipEntry(strZipEntryName);
zos.putNextEntry(entry);
zos.write(b, 0, (int) currDir.length());
zos.closeEntry();
}
}
}

269
src/java/orgs.list Normal file
View File

@ -0,0 +1,269 @@
ac
ad
ae
aero
af
ag
ai
al
am
an
ao
aq
ar
arpa
as
asia
at
au
aw
ax
az
ba
bb
bd
be
bf
bg
bh
bi
biz
bj
bm
bn
bo
br
bs
bt
bv
bw
by
bz
ca
cat
cc
cd
cf
cg
ch
ci
ck
cl
cm
cn
co
com
coop
cr
cu
cv
cx
cy
cz
de
dj
dk
dm
do
dz
ec
edu
ee
eg
er
es
et
eu
fi
fj
fk
fm
fo
fr
ga
gb
gd
ge
gf
gg
gh
gi
gl
gm
gn
gov
gp
gq
gr
gs
gt
gu
gw
gy
hk
hm
hn
hr
ht
hu
id
ie
il
im
in
info
int
io
iq
ir
is
it
je
jm
jo
jobs
jp
ke
kg
kh
ki
km
kn
kp
kr
kw
ky
kz
la
lb
lc
li
lk
lr
ls
lt
lu
lv
ly
ma
mc
md
me
mg
mh
mil
mk
ml
mm
mn
mo
mobi
mp
mq
mr
ms
mt
mu
museum
mv
mw
mx
my
mz
na
name
nc
ne
net
nf
ng
ni
nl
no
np
nr
nu
nz
om
org
pa
pe
pf
pg
ph
pk
pl
pm
pn
pr
pro
ps
pt
pw
py
qa
re
ro
rs
ru
rw
sa
sb
sc
sd
se
sg
sh
si
sj
sk
sl
sm
sn
so
sr
st
su
sv
sy
sz
tc
td
tel
tf
tg
th
tj
tk
tl
tm
tn
to
tp
tr
travel
tt
tv
tw
tz
ua
ug
uk
us
uy
uz
va
vc
ve
vg
vi
vn
vu
wf
ws
ye
yt
yu
za
zm
zw

View File

@ -0,0 +1,119 @@
/*
* 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.ivy.osgi.core;
import java.text.ParseException;
import org.apache.ivy.osgi.core.ManifestHeaderElement;
import org.apache.ivy.osgi.core.ManifestHeaderValue;
import junit.framework.TestCase;
public class ManifestHeaderTest extends TestCase {
public void testNormal() throws Exception {
ManifestHeaderElement simpleValue = new ManifestHeaderElement();
simpleValue.addValue("value");
ManifestHeaderValue header = new ManifestHeaderValue();
header.addElement(simpleValue);
assertEquals(header, new ManifestHeaderValue("value"));
ManifestHeaderElement simplePackage = new ManifestHeaderElement();
simplePackage.addValue("simple.package");
header.addElement(simplePackage);
assertEquals(header, new ManifestHeaderValue("value,simple.package"));
ManifestHeaderElement doubleValue = new ManifestHeaderElement();
doubleValue.addValue("value1");
doubleValue.addValue("value2");
ManifestHeaderValue headerDouble = new ManifestHeaderValue();
headerDouble.addElement(doubleValue);
assertEquals(headerDouble, new ManifestHeaderValue("value1;value2"));
ManifestHeaderElement versionValue = new ManifestHeaderElement();
versionValue.addValue("value1");
versionValue.addValue("value2");
versionValue.addAttribute("version", "1.2.3");
ManifestHeaderValue headerVersion = new ManifestHeaderValue();
headerVersion.addElement(versionValue);
assertEquals(headerVersion, new ManifestHeaderValue("value1;value2;version=1.2.3"));
ManifestHeaderElement optionValue1 = new ManifestHeaderElement();
optionValue1.addValue("value1");
optionValue1.addDirective("resolution", "optional");
ManifestHeaderElement optionValue2 = new ManifestHeaderElement();
optionValue2.addValue("value2");
optionValue2.addValue("value3");
optionValue2.addDirective("resolution", "mandatory");
optionValue2.addAttribute("version", "1.2.3");
ManifestHeaderValue headerOption = new ManifestHeaderValue();
headerOption.addElement(optionValue1);
headerOption.addElement(optionValue2);
assertEquals(headerOption, new ManifestHeaderValue(
"value1;resolution:=optional,value2;value3;resolution:=mandatory;version=1.2.3"));
ManifestHeaderElement quoteValue = new ManifestHeaderElement();
quoteValue.addValue("value1");
quoteValue.addAttribute("att", "value2;value3");
ManifestHeaderValue headerQuote = new ManifestHeaderValue();
headerQuote.addElement(quoteValue);
assertEquals(headerQuote, new ManifestHeaderValue("value1;att='value2;value3'"));
}
private void genericTestEquals(String v1, String v2) throws Exception {
assertEquals(new ManifestHeaderValue(v1), new ManifestHeaderValue(v2));
}
public void testSpaceAndQuote() throws Exception {
genericTestEquals("value1;att=value2;att2=other", "value1;att='value2';att2=other");
genericTestEquals("value1;att=value2;att2=other", "value1;att= 'value2' ;att2=other");
genericTestEquals("value1;att=value2;att2=other", "value1;att= value2 \t ;att2=other");
genericTestEquals("value1;att:=value2;att2=other", "value1;att:= 'value2' ;att2=other");
genericTestEquals("value1;att=value2;att2=other", "value1;att=\"value2\";att2=other");
}
public void testReflexivity() throws Exception {
genericTestEquals("value1;value2", "value2;value1");
genericTestEquals("value1,value2", "value2,value1");
genericTestEquals("value1;resolution:=mandatory;color:=red", "value1;color:=red;resolution:=mandatory");
genericTestEquals("value1;version=1.2.3;color=red", "value1;color=red;version=1.2.3");
genericTestEquals("value1;version=1.2.3;color:=red", "value1;color:=red;version=1.2.3");
}
public void testSyntaxError() throws Exception {
genericTestSyntaxError("value1=");
genericTestSyntaxError("value1;version=1;value2");
genericTestSyntaxError("value1;version=");
genericTestSyntaxError("value1;version:");
genericTestSyntaxError("value1;version:=");
genericTestSyntaxError("value1;=1");
genericTestSyntaxError("value1;att=''value");
}
private void genericTestSyntaxError(String value) {
try {
new ManifestHeaderValue(value);
fail("Syntax error not detected");
} catch (ParseException e) {
// error detected: OK
ManifestHeaderValue.writeParseException(System.out, value, e);
}
}
}

View File

@ -0,0 +1,76 @@
/*
* 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.ivy.osgi.core;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.util.HashSet;
import java.util.Set;
import org.apache.ivy.osgi.core.BundleInfo;
import org.apache.ivy.osgi.core.BundleRequirement;
import org.apache.ivy.osgi.core.ManifestParser;
import org.apache.ivy.osgi.util.VersionRange;
import org.junit.Test;
public class ManifestParserTest {
@Test
public void testParseManifest() throws Exception {
BundleInfo bundleInfo;
bundleInfo = ManifestParser.parseJarManifest(getClass().getClassLoader().getResourceAsStream(
"com.acme.alpha-1.0.0.20080101.jar"));
assertEquals("com.acme.alpha", bundleInfo.getSymbolicName());
assertEquals("1.0.0", bundleInfo.getVersion().numbersAsString());
assertEquals("20080101", bundleInfo.getVersion().qualifier());
assertEquals("1.0.0.20080101", bundleInfo.getVersion().toString());
assertEquals(2, bundleInfo.getRequires().size());
Set<BundleRequirement> expectedRequires = new HashSet<BundleRequirement>();
expectedRequires.add(new BundleRequirement(BundleInfo.BUNDLE_TYPE, "com.acme.bravo", new VersionRange("2.0.0"),
null));
expectedRequires.add(new BundleRequirement(BundleInfo.BUNDLE_TYPE, "com.acme.delta", new VersionRange("4.0.0"),
null));
assertEquals(expectedRequires, bundleInfo.getRequires());
assertEquals(0, bundleInfo.getExports().size());
assertEquals(2, bundleInfo.getImports().size());
final String importsList = bundleInfo.getImports().toString();
assertTrue(importsList.contains("com.acme.bravo"));
assertTrue(importsList.contains("com.acme.delta"));
bundleInfo = ManifestParser.parseJarManifest(getClass().getClassLoader().getResourceAsStream(
"com.acme.bravo-2.0.0.20080202.jar"));
assertNotNull(bundleInfo);
assertEquals("com.acme.bravo", bundleInfo.getSymbolicName());
assertEquals("2.0.0", bundleInfo.getVersion().numbersAsString());
assertEquals("20080202", bundleInfo.getVersion().qualifier());
assertEquals("2.0.0.20080202", bundleInfo.getVersion().toString());
assertEquals(1, bundleInfo.getRequires().size());
expectedRequires = new HashSet<BundleRequirement>();
expectedRequires.add(new BundleRequirement(BundleInfo.BUNDLE_TYPE, "com.acme.charlie",
new VersionRange("3.0.0"), null));
assertEquals(1, bundleInfo.getExports().size());
assertTrue(bundleInfo.getExports().toString().contains("com.acme.bravo"));
assertEquals(1, bundleInfo.getImports().size());
assertTrue(bundleInfo.getImports().toString().contains("com.acme.charlie"));
}
}

View File

@ -0,0 +1,63 @@
/*
* 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.ivy.osgi.ivy;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import org.apache.ivy.Ivy;
import org.apache.ivy.core.module.id.ModuleId;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.core.report.ResolveReport;
import org.apache.ivy.core.resolve.IvyNode;
import org.apache.ivy.core.resolve.ResolveOptions;
import org.apache.ivy.plugins.parser.AbstractModuleDescriptorParserTester;
public class IvyIntegrationTest extends AbstractModuleDescriptorParserTester {
private URL getTestResource(String resource) throws MalformedURLException {
return new File("java/test-ivy/" + resource).toURI().toURL();
}
@SuppressWarnings("unchecked")
public void testAcmeResolveAlpha() throws Exception {
final Ivy ivy = Ivy.newInstance();
ivy.configure(getTestResource("acme-ivysettings.xml"));
final ModuleRevisionId mrid = new ModuleRevisionId(new ModuleId("com.acme", "alpha"), "1.0+");
// final ModuleRevisionId mrid = new ModuleRevisionId(new ModuleId("com.acme", "delta"), "4+");
// final ModuleRevisionId mrid = new ModuleRevisionId(new ModuleId("com.acme", "echo"), "5+");
final ResolveOptions options = new ResolveOptions();
options.setConfs(new String[] { "default" });
final ResolveReport report = ivy.resolve(mrid, options, false);
assertEquals(5, report.getDependencies().size());
final String[] names = new String[] { "com.acme#alpha;1.0.0.20080101", "com.acme#bravo;2.0.0.20080202",
"com.acme#charlie;3.0.0.20080303", "com.acme#delta;4.0.0", "com.acme#echo;5.0.0" };
final Set<String> nodeNames = new HashSet<String>(Arrays.asList(names));
for (IvyNode node : (Collection<IvyNode>) report.getDependencies()) {
assertTrue(" Contains: " + node, nodeNames.contains(node.toString()));
}
}
}

View File

@ -0,0 +1,39 @@
/*
* 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.ivy.osgi.ivy;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import org.apache.ivy.osgi.ivy.internal.JarEntryResource;
import org.junit.Test;
public class JarHandlingRepositoryTest {
@Test
public void test() throws IOException {
final JarEntryResource resource = new JarEntryResource("java/test-bundles/jars/com.acme.alpha-1.0.0.20080101.jar!META-INF/MANIFEST.MF");
assertNotNull(resource.openStream());
assertTrue(resource.isLocal());
assertTrue(resource.exists());
}
}

View File

@ -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.ivy.osgi.ivy;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
import org.apache.ivy.core.settings.IvySettings;
import org.apache.ivy.osgi.ivy.OsgiIvyParser;
import org.apache.ivy.plugins.parser.ModuleDescriptorParser;
import org.apache.ivy.plugins.parser.ModuleDescriptorParserRegistry;
import org.apache.ivy.plugins.repository.url.URLResource;
import org.junit.Test;
public class OsgiIvyParserTest {
@Test
public void testSimple() throws Exception {
IvySettings settings = new IvySettings();
settings.load(new File("java/test-ivy/include/ivysettings.xml"));
URLResource includingResource = new URLResource(new File("java/test-ivy/include/ivy.xml").toURL());
ModuleDescriptorParser includingParser = ModuleDescriptorParserRegistry.getInstance().getParser(
includingResource);
assertTrue(includingParser instanceof OsgiIvyParser);
ModuleDescriptor includingMd = includingParser.parseDescriptor(settings, includingResource.getURL(), false);
assertNotNull(includingMd);
URLResource resultResource = new URLResource(new File("java/test-ivy/include/ivy-result.xml").toURL());
ModuleDescriptorParser resultParser = ModuleDescriptorParserRegistry.getInstance().getParser(resultResource);
ModuleDescriptor resultMd = resultParser.parseDescriptor(settings, resultResource.getURL(), false);
assertEquals(resultMd.getModuleRevisionId(), includingMd.getModuleRevisionId());
assertEquals(resultMd.getResolvedModuleRevisionId(), includingMd.getResolvedModuleRevisionId());
assertEquals(resultMd.getDescription(), includingMd.getDescription());
assertEquals(resultMd.getHomePage(), includingMd.getHomePage());
// assertEquals(resultMd.getLastModified(), includingMd.getLastModified());
assertEquals(resultMd.getStatus(), includingMd.getStatus());
assertEquals(resultMd.getExtraInfo(), includingMd.getExtraInfo());
assertArrayEquals(resultMd.getLicenses(), includingMd.getLicenses());
assertSetEquals(resultMd.getConfigurations(), includingMd.getConfigurations());
assertArrayEquals(resultMd.getAllArtifacts(), includingMd.getAllArtifacts());
assertEquals(resultMd.getDependencies().length, includingMd.getDependencies().length);
for (int i = 0; i < resultMd.getDependencies().length; i++) {
assertEquals(resultMd.getDependencies()[i].getDependencyRevisionId(), includingMd.getDependencies()[i]
.getDependencyRevisionId());
assertArrayEquals(resultMd.getDependencies()[i].getModuleConfigurations(), includingMd.getDependencies()[i]
.getModuleConfigurations());
}
}
private static <T1,T2> void assertSetEquals(T1[] expected, T2[] actual) {
assertSetEquals(Arrays.asList(expected), Arrays.asList(actual));
}
private static <T1,T2> void assertSetEquals(List<T1> expected, List<T2> actual) {
assertEquals(new HashSet<T1>(expected), new HashSet<T2>(actual));
}
}

View File

@ -0,0 +1,146 @@
/*
* 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.ivy.osgi.ivy;
import static java.lang.ClassLoader.getSystemResource;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import org.apache.ivy.core.module.descriptor.Artifact;
import org.apache.ivy.core.module.descriptor.DefaultArtifact;
import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
import org.apache.ivy.core.module.id.ModuleId;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.core.settings.IvySettings;
import org.apache.ivy.osgi.ivy.OsgiManifestParser;
import org.apache.ivy.plugins.parser.AbstractModuleDescriptorParserTester;
import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorParserTest;
import org.apache.ivy.plugins.repository.url.URLResource;
import org.apache.ivy.util.FileUtil;
/**
* @author jerome@benois.fr
*/
public class OsgiManifestParserTest extends AbstractModuleDescriptorParserTester {
private URL getTestResource(String resource) throws MalformedURLException {
return new File("java/test-ivy/" + resource).toURI().toURL();
}
public void testAccept() throws Exception {
assertTrue(OsgiManifestParser.getInstance().accept(
new URLResource(getTestResource("osgi/eclipse/plugins/test-simple/META-INF/MANIFEST.MF"))));
assertFalse(OsgiManifestParser.getInstance().accept(
new URLResource(XmlModuleDescriptorParserTest.class.getResource("test.xml"))));
}
public void testSimple() throws Exception {
final ModuleDescriptor md = OsgiManifestParser.getInstance().parseDescriptor(new IvySettings(),
getTestResource("osgi/eclipse/plugins/test-simple/META-INF/MANIFEST.MF"), false);
assertNotNull(md);
assertSimpleModuleDescriptor(md);
}
public void testSimpleFromJar() throws Exception {
final ModuleDescriptor md = OsgiManifestParser.getInstance().parseDescriptor(new IvySettings(),
getTestResource("test-simple.jar"), false);
assertNotNull(md);
assertSimpleModuleDescriptor(md);
}
public void testFull() throws Exception {
final ModuleDescriptor md = OsgiManifestParser.getInstance().parseDescriptor(new IvySettings(),
getTestResource("osgi/eclipse/plugins/test-full/META-INF/MANIFEST.MF"), false);
assertNotNull(md);
assertSimpleModuleDescriptor(md);
assertDependencies(md);
}
public void testFullFromJar() throws Exception {
final ModuleDescriptor md = OsgiManifestParser.getInstance().parseDescriptor(new IvySettings(),
getTestResource("test-full.jar"), false);
assertNotNull(md);
assertSimpleModuleDescriptor(md);
assertDependencies(md);
}
public void testJB() throws Exception {
final ModuleRevisionId mrid = new ModuleRevisionId(new ModuleId("org", "name"), "revisionId");
final Artifact artifact = new DefaultArtifact(mrid, new Date(), "META-INF/MANIFEST", "manifest", "MF", true);
System.out.println(artifact);
}
private void assertSimpleModuleDescriptor(ModuleDescriptor md) throws Exception {
final ModuleRevisionId mrid = ModuleRevisionId.newInstance("org.eclipse", "datatools.connectivity.ui",
"1.0.1.200708231");
assertEquals(mrid, md.getModuleRevisionId());
assertNotNull(md.getConfigurations());
assertEquals(3, md.getConfigurations().length);
assertNotNull(md.getConfiguration("default"));
assertNotNull(md.getAllArtifacts());
assertEquals(2, md.getAllArtifacts().length);
final Artifact[] artifact = md.getArtifacts("default");
assertEquals(1, artifact.length);
assertEquals(mrid, artifact[0].getModuleRevisionId());
assertEquals("org.eclipse.datatools.connectivity.ui", artifact[0].getName());
assertEquals("jar", artifact[0].getExt());
assertEquals("jar", artifact[0].getType());
}
private void assertDependencies(ModuleDescriptor md) throws Exception {
final DependencyDescriptor[] dds = md.getDependencies();
assertNotNull(dds);
Set<ModuleRevisionId> actual = new HashSet<ModuleRevisionId>();
for (DependencyDescriptor dd : md.getDependencies()) {
actual.add(dd.getDependencyRevisionId());
}
Set<ModuleRevisionId> expected = new HashSet<ModuleRevisionId>();
expected.add(ModuleRevisionId.newInstance("org.eclipse", "core.runtime", "[3.2.0,4.0.0)"));
expected.add(ModuleRevisionId.newInstance("org.eclipse", "core.resources", "[3.2.0,4.0.0)"));
expected.add(ModuleRevisionId.newInstance("org.eclipse", "ui", "[3.2.0,4.0.0)"));
expected.add(ModuleRevisionId.newInstance("org.eclipse", "ui.views", "[3.2.0,4.0.0)"));
expected.add(ModuleRevisionId.newInstance("org.eclipse", "datatools.connectivity", "[0.9.1,1.5.0)"));
expected.add(ModuleRevisionId.newInstance("org.eclipse", "ui.navigator", "[3.2.0,4.0.0)"));
expected.add(ModuleRevisionId.newInstance("org.eclipse", "core.expressions", "[3.2.0,4.0.0)"));
expected.add(ModuleRevisionId.newInstance("com.ibm", "icu", "[3.4.0,4.0.0)"));
expected.add(ModuleRevisionId.newInstance("org.eclipse", "ltk.core.refactoring", "[3.2.0,4.0.0)"));
expected.add(ModuleRevisionId.newInstance("org.eclipse", "datatools.help", "[1.0.0,2.0.0)"));
expected.add(ModuleRevisionId.newInstance("org.eclipse", "help", "[3.2.0,4.0.0)"));
expected.add(ModuleRevisionId.newInstance("org.eclipse", "help.base", "[3.2.0,4.0.0)"));
assertEquals(expected, actual);
}
private String readEntirely(String resource) throws IOException {
return FileUtil
.readEntirely(new BufferedReader(new InputStreamReader(getSystemResource(resource).openStream())));
}
}

View File

@ -0,0 +1,46 @@
/*
* 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.ivy.osgi.obr;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.io.File;
import java.io.FileInputStream;
import org.apache.ivy.osgi.obr.xml.OBRXMLParser;
import org.apache.ivy.osgi.repo.BundleRepo;
import org.apache.ivy.util.Message;
import org.junit.Test;
public class OBRParserTest {
@Test
public void testParse() throws Exception {
BundleRepo repo = OBRXMLParser.parse(new FileInputStream(new File("java/test-obr/obr.xml")));
assertNotNull(repo);
System.out.println(repo.getBundles().size() + " bundles successfully parsed, " + Message.getProblems().size() + " errors");
for (Object error : Message.getProblems()) {
System.err.println(error);
}
assertEquals("OBR/Releases", repo.getName());
assertEquals(new Long(1253581430652l), repo.getLastModified());
}
}

View File

@ -0,0 +1,64 @@
/*
* 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.ivy.osgi.obr;
import java.text.ParseException;
import junit.framework.Assert;
import org.apache.ivy.osgi.obr.filter.AndFilter;
import org.apache.ivy.osgi.obr.filter.CompareFilter;
import org.apache.ivy.osgi.obr.filter.RequirementFilterParser;
import org.apache.ivy.osgi.obr.filter.CompareFilter.Operator;
import org.apache.ivy.osgi.obr.xml.RequirementFilter;
import org.junit.Test;
public class RequirementFilterTest {
@Test
public void testParser() throws Exception {
assertParseFail("c>2");
assertParseFail("");
assertParseFail(")");
RequirementFilter cgt2 = new CompareFilter("c", Operator.GREATER_THAN, "2");
checkParse(cgt2, "(c>2)");
RequirementFilter twoeqd = new CompareFilter("2", Operator.EQUALS, "d");
checkParse(twoeqd, "(2=d)");
RequirementFilter foodorbarge0dot0 = new CompareFilter("foo.bar", Operator.GREATER_OR_EQUAL, "0.0");
checkParse(foodorbarge0dot0, "(foo.bar>=0.0)");
RequirementFilter and = new AndFilter(foodorbarge0dot0);
checkParse(and, "(&(foo.bar>=0.0))");
RequirementFilter and2 = new AndFilter(cgt2, twoeqd, foodorbarge0dot0);
checkParse(and2, "(&(c>2)(2=d)(foo.bar>=0.0))");
}
private void assertParseFail(String toParse) {
try {
RequirementFilterParser.parse(toParse);
Assert.fail("Expecting a ParseException");
} catch (ParseException e) {
// OK
}
}
private void checkParse(RequirementFilter expected, String toParse) throws ParseException {
RequirementFilter parsed = RequirementFilterParser.parse(toParse);
Assert.assertEquals(expected, parsed);
}
}

View File

@ -0,0 +1,298 @@
/*
* 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.ivy.osgi.repo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.FileInputStream;
import java.text.ParseException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.jar.JarInputStream;
import org.apache.ivy.Ivy;
import org.apache.ivy.core.cache.RepositoryCacheManager;
import org.apache.ivy.core.module.descriptor.Artifact;
import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor;
import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.core.report.ArtifactDownloadReport;
import org.apache.ivy.core.report.DownloadReport;
import org.apache.ivy.core.report.DownloadStatus;
import org.apache.ivy.core.report.ResolveReport;
import org.apache.ivy.core.resolve.DownloadOptions;
import org.apache.ivy.core.resolve.ResolveData;
import org.apache.ivy.core.resolve.ResolveOptions;
import org.apache.ivy.core.resolve.ResolvedModuleRevision;
import org.apache.ivy.core.settings.IvySettings;
import org.apache.ivy.osgi.core.BundleInfo;
import org.apache.ivy.osgi.core.ManifestParser;
import org.apache.ivy.osgi.repo.BundleInfoAdapter;
import org.apache.ivy.osgi.repo.BundleRepoResolver;
import org.apache.ivy.osgi.repo.BundleRepoResolver.RequirementStrategy;
import org.apache.ivy.plugins.resolver.DependencyResolver;
import org.apache.ivy.plugins.resolver.DualResolver;
import org.apache.ivy.plugins.resolver.FileSystemResolver;
import org.junit.Before;
import org.junit.Test;
public class BundleRepoResolverTest {
private static final ModuleRevisionId MRID_TEST_BUNDLE = ModuleRevisionId.newInstance("", "org.apache.ivy.osgitestbundle",
"1.2.3", BundleInfoAdapter.OSGI_BUNDLE);
private static final ModuleRevisionId MRID_TEST_BUNDLE_IMPORTING = ModuleRevisionId.newInstance("",
"org.apache.ivy.osgi.testbundle.importing", "3.2.1", BundleInfoAdapter.OSGI_BUNDLE);
private static final ModuleRevisionId MRID_TEST_BUNDLE_IMPORTING_VERSION = ModuleRevisionId.newInstance("",
"org.apache.ivy.osgi.testbundle.importing.version", "3.2.1", BundleInfoAdapter.OSGI_BUNDLE);
private static final ModuleRevisionId MRID_TEST_BUNDLE_IMPORTING_OPTIONAL = ModuleRevisionId.newInstance("",
"org.apache.ivy.osgi.testbundle.importing.optional", "3.2.1", BundleInfoAdapter.OSGI_BUNDLE);
private static final ModuleRevisionId MRID_TEST_BUNDLE_USE = ModuleRevisionId.newInstance("",
"org.apache.ivy.osgi.testbundle.use", "2.2.2", BundleInfoAdapter.OSGI_BUNDLE);
private static final ModuleRevisionId MRID_TEST_BUNDLE_EXPORTING_AMBIGUITY = ModuleRevisionId.newInstance("",
"org.apache.ivy.osgi.testbundle.exporting.ambiguity", "3.3.3", BundleInfoAdapter.OSGI_BUNDLE);
private IvySettings settings;
private File cache;
private ResolveData data;
private Ivy ivy;
private BundleRepoResolver bundleResolver;
private BundleRepoResolver bundleUrlResolver;
private DualResolver dualResolver;
@Before
public void setUp() throws Exception {
settings = new IvySettings();
bundleResolver = new BundleRepoResolver();
bundleResolver.setRepoXmlFile(new File("java/test-repo/bundlerepo/repo.xml").getAbsolutePath());
bundleResolver.setName("bundle");
bundleResolver.setSettings(settings);
settings.addResolver(bundleResolver);
bundleUrlResolver = new BundleRepoResolver();
bundleUrlResolver
.setRepoXmlURL(new File("java/test-repo/bundlerepo/repo.xml").toURI().toURL().toExternalForm());
bundleUrlResolver.setName("bundleurl");
bundleUrlResolver.setSettings(settings);
settings.addResolver(bundleUrlResolver);
dualResolver = new DualResolver();
BundleRepoResolver resolver = new BundleRepoResolver();
resolver.setRepoXmlFile("java/test-repo/ivyrepo/repo.xml");
resolver.setName("dual-bundle");
resolver.setSettings(settings);
dualResolver.add(resolver);
dualResolver.setName("dual");
File ivyrepo = new File("java/test-repo/ivyrepo");
FileSystemResolver fileSystemResolver = new FileSystemResolver();
fileSystemResolver.addIvyPattern(ivyrepo.getAbsolutePath() + "/[organisation]/[module]/[revision]/ivy.xml");
fileSystemResolver.addArtifactPattern(ivyrepo.getAbsolutePath()
+ "/[organisation]/[module]/[revision]/[type]s/[artifact]-[revision].[ext]");
fileSystemResolver.setName("dual-file");
fileSystemResolver.setSettings(settings);
dualResolver.add(fileSystemResolver);
settings.addResolver(dualResolver);
settings.setDefaultResolver("bundle");
cache = new File("build/cache");
cache.mkdirs();
settings.setDefaultCache(cache);
ivy = new Ivy();
ivy.setSettings(settings);
ivy.bind();
ivy.getResolutionCacheManager().clean();
RepositoryCacheManager[] caches = settings.getRepositoryCacheManagers();
for (int i = 0; i < caches.length; i++) {
caches[i].clean();
}
data = new ResolveData(ivy.getResolveEngine(), new ResolveOptions());
}
@Test
public void testSimpleResolve() throws Exception {
ModuleRevisionId mrid = ModuleRevisionId.newInstance("", "org.apache.ivy.osgi.testbundle", "1.2.3",
BundleInfoAdapter.OSGI_BUNDLE);
genericTestResolveDownload(bundleResolver, mrid);
}
@Test
public void testSimpleUrlResolve() throws Exception {
ModuleRevisionId mrid = ModuleRevisionId.newInstance("", "org.apache.ivy.osgi.testbundle", "1.2.3",
BundleInfoAdapter.OSGI_BUNDLE);
genericTestResolveDownload(bundleUrlResolver, mrid);
}
@Test
public void testResolveDual() throws Exception {
ModuleRevisionId mrid = ModuleRevisionId.newInstance("", "org.apache.ivy.osgi.testbundle", "1.2.3",
BundleInfoAdapter.OSGI_BUNDLE);
genericTestResolveDownload(dualResolver, mrid);
}
private void genericTestResolveDownload(DependencyResolver resolver, ModuleRevisionId mrid) throws ParseException {
ResolvedModuleRevision rmr = resolver.getDependency(new DefaultDependencyDescriptor(mrid, false), data);
assertNotNull(rmr);
assertEquals(mrid, rmr.getId());
Artifact artifact = rmr.getDescriptor().getAllArtifacts()[0];
DownloadReport report = resolver.download(new Artifact[] { artifact }, new DownloadOptions());
assertNotNull(report);
assertEquals(1, report.getArtifactsReports().length);
ArtifactDownloadReport ar = report.getArtifactReport(artifact);
assertNotNull(ar);
assertEquals(artifact, ar.getArtifact());
assertEquals(DownloadStatus.SUCCESSFUL, ar.getDownloadStatus());
// test to ask to download again, should use cache
report = resolver.download(new Artifact[] { artifact }, new DownloadOptions());
assertNotNull(report);
assertEquals(1, report.getArtifactsReports().length);
ar = report.getArtifactReport(artifact);
assertNotNull(ar);
assertEquals(artifact, ar.getArtifact());
assertEquals(DownloadStatus.NO, ar.getDownloadStatus());
}
@Test
public void testResolveImporting() throws Exception {
String jarName = "org.apache.ivy.osgi.testbundle.importing_3.2.1.jar";
genericTestResolve(jarName, "default", MRID_TEST_BUNDLE);
}
@Test
public void testResolveImportingOptional() throws Exception {
String jarName = "org.apache.ivy.osgi.testbundle.importing.optional_3.2.1.jar";
genericTestResolve(jarName, "default");
genericTestResolve(jarName, "optional", MRID_TEST_BUNDLE);
genericTestResolve(jarName, "transitive-optional", MRID_TEST_BUNDLE);
}
@Test
public void testResolveImportingTransitiveOptional() throws Exception {
String jarName = "org.apache.ivy.osgi.testbundle.importing.transitiveoptional_3.2.1.jar";
genericTestResolve(jarName, "default");
genericTestResolve(jarName, "optional", MRID_TEST_BUNDLE_IMPORTING_OPTIONAL);
genericTestResolve(jarName, "transitive-optional", MRID_TEST_BUNDLE, MRID_TEST_BUNDLE_IMPORTING_OPTIONAL);
}
@Test
public void testResolveImportingVersion() throws Exception {
String jarName = "org.apache.ivy.osgi.testbundle.importing.version_3.2.1.jar";
genericTestResolve(jarName, "default", MRID_TEST_BUNDLE);
}
@Test
public void testResolveImportingRangeVersion() throws Exception {
String jarName = "org.apache.ivy.osgi.testbundle.importing.rangeversion_3.2.1.jar";
genericTestResolve(jarName, "default", MRID_TEST_BUNDLE);
}
@Test
public void testResolveUse() throws Exception {
String jarName = "org.apache.ivy.osgi.testbundle.use_2.2.2.jar";
genericTestResolve(jarName, "default");
}
@Test
public void testResolveImportingUse() throws Exception {
String jarName = "org.apache.ivy.osgi.testbundle.importing.use_3.2.1.jar";
genericTestResolve(jarName, "default", MRID_TEST_BUNDLE_USE, MRID_TEST_BUNDLE_IMPORTING, MRID_TEST_BUNDLE);
}
@Test
public void testResolveRequire() throws Exception {
String jarName = "org.apache.ivy.osgi.testbundle.require_1.1.1.jar";
genericTestResolve(jarName, "default", MRID_TEST_BUNDLE, MRID_TEST_BUNDLE_IMPORTING_VERSION);
}
@Test
public void testResolveOptionalConf() throws Exception {
String jarName = "org.apache.ivy.osgi.testbundle.require_1.1.1.jar";
genericTestResolve(jarName, "optional", MRID_TEST_BUNDLE, MRID_TEST_BUNDLE_IMPORTING_VERSION);
}
@Test
public void testResolveImportAmbiguity() throws Exception {
String jarName = "org.apache.ivy.osgi.testbundle.importing.ambiguity_3.2.1.jar";
bundleResolver.setImportPackageStrategy(RequirementStrategy.first);
genericTestResolve(jarName, "default", MRID_TEST_BUNDLE_EXPORTING_AMBIGUITY);
}
@Test
public void testResolveImportNoAmbiguity() throws Exception {
String jarName = "org.apache.ivy.osgi.testbundle.importing.ambiguity_3.2.1.jar";
bundleResolver.setImportPackageStrategy(RequirementStrategy.noambiguity);
genericTestFailingResolve(jarName, "default");
}
@Test
public void testResolveRequireAmbiguity() throws Exception {
String jarName = "org.apache.ivy.osgi.testbundle.require.ambiguity_1.1.1.jar";
bundleResolver.setImportPackageStrategy(RequirementStrategy.noambiguity);
genericTestResolve(jarName, "default", MRID_TEST_BUNDLE, MRID_TEST_BUNDLE_IMPORTING_VERSION);
}
private void genericTestResolve(String jarName, String conf, ModuleRevisionId... expectedMrids) throws Exception {
JarInputStream in = new JarInputStream(new FileInputStream("java/test-repo/bundlerepo/" + jarName));
BundleInfo bundleInfo = ManifestParser.parseManifest(in.getManifest());
DefaultModuleDescriptor md = BundleInfoAdapter.toModuleDescriptor(bundleInfo, null);
ResolveReport resolveReport = ivy.resolve(md, new ResolveOptions().setConfs(new String[] { conf })
.setOutputReport(false));
assertFalse("resolve failed " + resolveReport.getProblemMessages(), resolveReport.hasError());
Set<ModuleRevisionId> actual = new HashSet<ModuleRevisionId>();
@SuppressWarnings("unchecked")
List<Artifact> artifacts = resolveReport.getArtifacts();
for (Artifact artfact : artifacts) {
actual.add(artfact.getModuleRevisionId());
}
Set<ModuleRevisionId> expected = new HashSet<ModuleRevisionId>(Arrays.asList(expectedMrids));
assertEquals(expected, actual);
}
private void genericTestFailingResolve(String jarName, String conf) throws Exception {
JarInputStream in = new JarInputStream(new FileInputStream("java/test-repo/bundlerepo/" + jarName));
BundleInfo bundleInfo = ManifestParser.parseManifest(in.getManifest());
DefaultModuleDescriptor md = BundleInfoAdapter.toModuleDescriptor(bundleInfo, null);
ResolveReport resolveReport = ivy.resolve(md, new ResolveOptions().setConfs(new String[] { conf })
.setOutputReport(false));
assertTrue(resolveReport.hasError());
}
}

View File

@ -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.ivy.osgi.repo;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.ParseException;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;
import junit.framework.TestCase;
import org.apache.ivy.core.settings.IvySettings;
import org.apache.ivy.osgi.obr.xml.OBRXMLParser;
import org.apache.ivy.osgi.obr.xml.OBRXMLWriter;
import org.apache.ivy.osgi.repo.BundleRepo;
import org.apache.ivy.osgi.repo.FSManifestIterable;
import org.apache.ivy.osgi.repo.RepositoryManifestIterable;
import org.apache.ivy.osgi.repo.ResolverManifestIterable;
import org.apache.ivy.plugins.repository.file.FileRepository;
import org.apache.ivy.plugins.resolver.FileSystemResolver;
import org.apache.tools.ant.BuildException;
import org.xml.sax.SAXException;
public class BundleRepoTest extends TestCase {
public void testFS() throws Exception {
FSManifestIterable it = new FSManifestIterable(new File("java/test-repo/bundlerepo"), "");
BundleRepo repo = new BundleRepo();
repo.populate(it);
BundleRepo repo2 = OBRXMLParser.parse(new FileInputStream("java/test-repo/bundlerepo/repo.xml"));
assertEquals(repo, repo2);
}
public void testFileRepo() throws Exception {
RepositoryManifestIterable it = new RepositoryManifestIterable(new FileRepository(new File(
"java/test-repo/bundlerepo")));
BundleRepo repo = new BundleRepo();
repo.populate(it);
BundleRepo repo2 = OBRXMLParser.parse(new FileInputStream("java/test-repo/bundlerepo/repo.xml"));
assertEquals(repo, repo2);
}
public void testResolver() throws Exception {
FileSystemResolver fileSystemResolver = new FileSystemResolver();
fileSystemResolver.setName("test");
File ivyrepo = new File("java/test-repo/ivyrepo");
fileSystemResolver.addIvyPattern(ivyrepo.getAbsolutePath() + "/[organisation]/[module]/[revision]/ivy.xml");
fileSystemResolver.addArtifactPattern(ivyrepo.getAbsolutePath()
+ "/[organisation]/[module]/[revision]/[type]s/[artifact]-[revision].[ext]");
fileSystemResolver.setSettings(new IvySettings());
ResolverManifestIterable it = new ResolverManifestIterable(fileSystemResolver);
BundleRepo repo = new BundleRepo();
repo.populate(it);
BundleRepo repo2 = OBRXMLParser.parse(new FileInputStream("java/test-repo/ivyrepo/repo.xml"));
assertEquals(repo, repo2);
}
public void testXMLSerialisation() throws SAXException, ParseException, IOException {
FSManifestIterable it = new FSManifestIterable(new File("java/test-repo/bundlerepo"), "");
BundleRepo repo = new BundleRepo();
repo.populate(it);
SAXTransformerFactory tf = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
TransformerHandler hd;
try {
hd = tf.newTransformerHandler();
} catch (TransformerConfigurationException e) {
throw new BuildException("Sax configuration error: " + e.getMessage(), e);
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
StreamResult stream = new StreamResult(out);
hd.setResult(stream);
OBRXMLWriter.writeBundles(repo.getBundles(), hd);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
BundleRepo repo2 = OBRXMLParser.parse(in);
assertEquals(repo, repo2);
}
}

View File

@ -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.ivy.osgi.util;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import org.apache.ivy.osgi.util.ArtifactTokens;
import org.junit.Test;
public class ArtifactTokensTest {
@Test
public void testGoodMatching() {
final String repoResource = "java/test-ivy/osgi/eclipse/plugins/org.eclipse.datatools.connectivity.ui_1.0.1.v200808121010";
final ArtifactTokens tokens = new ArtifactTokens(repoResource);
assertEquals("java/test-ivy/osgi/eclipse/plugins/", tokens.prefix);
assertEquals("org.eclipse.datatools.connectivity.ui", tokens.module);
assertEquals("1.0.1", tokens.version.numbersAsString());
assertEquals("v200808121010", tokens.version.qualifier());
assertFalse(tokens.isJar);
}
@Test
public void testGoodMatching2() {
final String repoResource = "java/test-ivy/osgi/eclipse/plugins/org.eclipse.datatools.connectivity.ui_1.0.1";
final ArtifactTokens tokens = new ArtifactTokens(repoResource);
assertEquals("java/test-ivy/osgi/eclipse/plugins/", tokens.prefix);
assertEquals("org.eclipse.datatools.connectivity.ui", tokens.module);
assertEquals("1.0.1", tokens.version.numbersAsString());
assertEquals("", tokens.version.qualifier());
assertFalse(tokens.isJar);
}
@Test
public void testGoodMatching3() {
final String repoResource = "java/test-ivy/osgi/eclipse/plugins/org.myorg.module.one_3.21.100.v20070530";
final ArtifactTokens tokens = new ArtifactTokens(repoResource);
assertEquals("java/test-ivy/osgi/eclipse/plugins/", tokens.prefix);
assertEquals("org.myorg.module.one", tokens.module);
assertEquals("3.21.100", tokens.version.numbersAsString());
assertEquals("v20070530", tokens.version.qualifier());
assertFalse(tokens.isJar);
}
@Test
public void testGoodMatching4() {
final String repoResource = "java/test-ivy/osgi/eclipse/plugins/org.eclipse.mylyn.tasks.ui_3.0.1.v20080721-2100-e33.jar";
// String repoResource = "java/test-ivy/osgi/eclipse/plugins/org.eclipse.mylyn.tasks.ui_3.0.1.v20080721.jar";
final ArtifactTokens tokens = new ArtifactTokens(repoResource);
assertEquals("java/test-ivy/osgi/eclipse/plugins/", tokens.prefix);
assertEquals("org.eclipse.mylyn.tasks.ui", tokens.module);
assertEquals("3.0.1", tokens.version.numbersAsString());
assertEquals("v20080721-2100-e33", tokens.version.qualifier());
assertTrue(tokens.isJar);
}
@Test
public void testBadMatching() {
final String repoResource = "java/test-ivy/osgi/eclipse/plugins/fake";
final ArtifactTokens tokens = new ArtifactTokens(repoResource);
assertNull(tokens.prefix);
assertNull(tokens.module);
assertNull(tokens.version);
}
}

View File

@ -0,0 +1,78 @@
/*
* 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.ivy.osgi.util;
import static org.junit.Assert.*;
import org.apache.ivy.osgi.util.NameUtil;
import org.apache.ivy.osgi.util.NameUtil.OrgAndName;
import org.junit.*;
public class NameUtilTest {
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@Test
public void testAsOrgAndName() {
OrgAndName oan;
oan = NameUtil.instance().asOrgAndName("foo");
assertEquals("foo", oan.org);
assertEquals("foo", oan.name);
oan = NameUtil.instance().asOrgAndName("java.foo");
assertEquals("java", oan.org);
assertEquals("foo", oan.name);
oan = NameUtil.instance().asOrgAndName("java.foo.bar");
assertEquals("java", oan.org);
assertEquals("foo.bar", oan.name);
oan = NameUtil.instance().asOrgAndName("javax.foo");
assertEquals("javax", oan.org);
assertEquals("foo", oan.name);
oan = NameUtil.instance().asOrgAndName("javax.foo.bar");
assertEquals("javax", oan.org);
assertEquals("foo.bar", oan.name);
oan = NameUtil.instance().asOrgAndName("org.eclipse.foo");
assertEquals("org.eclipse", oan.org);
assertEquals("foo", oan.name);
oan = NameUtil.instance().asOrgAndName("org.eclipse.foo.bar");
assertEquals("org.eclipse", oan.org);
assertEquals("foo.bar", oan.name);
oan = NameUtil.instance().asOrgAndName("com.eclipse.foo.bar");
assertEquals("com.eclipse", oan.org);
assertEquals("foo.bar", oan.name);
oan = NameUtil.instance().asOrgAndName("net.eclipse.foo.bar");
assertEquals("net.eclipse", oan.org);
assertEquals("foo.bar", oan.name);
}
}

View File

@ -0,0 +1,37 @@
/*
* 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.ivy.osgi.util;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.apache.ivy.osgi.util.ParseUtil;
import org.junit.Test;
public class ParseUtilTest {
@Test
public void testParse() {
final String[] result = ParseUtil.parseDelimitedString("bravo;bundle-version=\"1.0.0\", delta;bundle-version=\"1.0.0\"", ",");
assertNotNull(result);
assertEquals(2, result.length);
assertEquals("bravo;bundle-version=\"1.0.0\"", result[0]);
assertEquals("delta;bundle-version=\"1.0.0\"", result[1]);
}
}

View File

@ -0,0 +1,96 @@
/*
* 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.ivy.osgi.util;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.apache.ivy.osgi.util.Version;
import org.apache.ivy.osgi.util.VersionRange;
import org.junit.Test;
public class VersionRangeTest {
@Test
public void testParse() throws Exception {
assertEquals(new VersionRange(false, new Version("1.0.0"), false, null), new VersionRange("1.0.0"));
assertEquals(new VersionRange(false, new Version("1.0.0"), false, null), new VersionRange(" 1.0.0 "));
assertEquals(new VersionRange(false, new Version("1.0.0"), false, new Version("2.0.0")), new VersionRange(
"[1.0.0,2.0.0]"));
assertEquals(new VersionRange(false, new Version("1.0.0"), false, new Version("2.0.0")), new VersionRange(
"[1.0.0 , 2.0.0]"));
assertEquals(new VersionRange(false, new Version("1.0.0"), false, new Version("2.0.0")), new VersionRange(
" [1.0.0,2.0.0] "));
assertEquals(new VersionRange(false, new Version("1.0.0"), false, new Version("2.0.0")), new VersionRange(
"[ 1.0.0,2.0.0 ]"));
assertEquals(new VersionRange(false, new Version("1.0.0.A"), false, null), new VersionRange("1.0.0.A"));
}
@Test
public void testContains() throws Exception {
assertFalse(new VersionRange("1").contains("0.9"));
assertTrue(new VersionRange("1").contains("1"));
assertTrue(new VersionRange("1").contains("1.0"));
assertTrue(new VersionRange("1").contains("1.0.0"));
assertTrue(new VersionRange("1").contains("2"));
assertTrue(new VersionRange("1").contains("1.0.1"));
assertFalse(new VersionRange("1.2.3").contains("1.0.0"));
assertTrue(new VersionRange("1.2.3").contains("1.2.3"));
assertTrue(new VersionRange("1.2.3").contains("1.2.4"));
assertTrue(new VersionRange("1.2.3").contains("1.2.3.A"));
assertFalse(new VersionRange("[1.0.0,2.0.0]").contains("0.9.0"));
assertTrue(new VersionRange("[1.0.0,2.0.0]").contains("1.0.0"));
assertTrue(new VersionRange("[1.0.0,2.0.0]").contains("1.999.999"));
assertTrue(new VersionRange("[1.0.0,2.0.0]").contains("2.0.0"));
assertFalse(new VersionRange("[1.0.0,2.0.0]").contains("2.1.0"));
assertFalse(new VersionRange("[1.0.0,2.0.0]").contains("2.0.1"));
assertFalse(new VersionRange("[1.0.0,2]").contains("0.9.0"));
assertTrue(new VersionRange("[1.0.0,2]").contains("1.0.0"));
assertTrue(new VersionRange("[1.0.0,2]").contains("1.999.999"));
assertTrue(new VersionRange("[1.0.0,2]").contains("2.0.0"));
assertFalse(new VersionRange("[1.0.0,2]").contains("2.1.0"));
assertFalse(new VersionRange("[1.0.0,2]").contains("2.0.1"));
assertFalse(new VersionRange("(1.0.0,2.0.0)").contains("0.9.0"));
assertFalse(new VersionRange("(1.0.0,2.0.0)").contains("1.0.0"));
assertTrue(new VersionRange("(1.0.0,2.0.0)").contains("1.999.999"));
assertFalse(new VersionRange("(1.0.0,2.0.0)").contains("2.0.0"));
assertFalse(new VersionRange("(1.0.0,2.0.0)").contains("2.1.0"));
assertFalse(new VersionRange("(1.0.0,2.0.0)").contains("2.0.1"));
assertFalse(new VersionRange("(1.0.0,)").contains("0.9.0"));
assertFalse(new VersionRange("(1.0.0,)").contains("1.0.0"));
assertTrue(new VersionRange("(1.0.0,)").contains("1.999.999"));
assertTrue(new VersionRange("(1.0.0,)").contains("2.0.0"));
assertTrue(new VersionRange("(1.0.0,)").contains("2.1.0"));
assertTrue(new VersionRange("(1.0.0,)").contains("2.0.1"));
assertFalse(new VersionRange("(1.0.0,]").contains("0.9.0"));
assertFalse(new VersionRange("(1.0.0,]").contains("1.0.0"));
assertTrue(new VersionRange("(1.0.0,]").contains("1.999.999"));
assertTrue(new VersionRange("(1.0.0,]").contains("2.0.0"));
assertTrue(new VersionRange("(1.0.0,]").contains("2.1.0"));
assertTrue(new VersionRange("(1.0.0,]").contains("2.0.1"));
}
}

View File

@ -0,0 +1,66 @@
/*
* 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.ivy.osgi.util;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.apache.ivy.osgi.util.Version;
import org.junit.Test;
public class VersionTest {
@Test
public void testParsing() {
Version v;
v = new Version("1");
assertEquals("1.0.0", v.numbersAsString());
assertEquals("", v.qualifier());
v = new Version("1.2");
assertEquals("1.2.0", v.numbersAsString());
assertEquals("", v.qualifier());
v = new Version("1.2.3");
assertEquals("1.2.3", v.numbersAsString());
assertEquals("", v.qualifier());
v = new Version("1.2.3.abc");
assertEquals("1.2.3.abc", v.toString());
assertEquals("abc", v.qualifier());
}
@Test
public void testCompareTo() {
assertTrue(new Version("1.2.3").compareTo(new Version("1.2.3")) == 0);
assertTrue(new Version("1.2.3").compareTo(new Version("1.2.2")) > 0);
assertTrue(new Version("1.2.3").compareTo(new Version("1.1.3")) > 0);
assertTrue(new Version("1.2.3").compareTo(new Version("0.2.3")) > 0);
assertTrue(new Version("1.2.3.xyz").compareTo(new Version("1.2.3")) > 0);
assertTrue(new Version("1.2.3.xyz").compareTo(new Version("1.2.3.abc")) > 0);
assertTrue(new Version("1.2.3").compareTo(new Version("1.2.4")) < 0);
assertTrue(new Version("1.2.3").compareTo(new Version("1.3.3")) < 0);
assertTrue(new Version("1.2.3").compareTo(new Version("2.2.3")) < 0);
assertTrue(new Version("1.2.3").compareTo(new Version("1.2.3.xyz")) < 0);
assertTrue(new Version("1.2.3.abc").compareTo(new Version("1.2.3.xyz")) < 0);
}
}

View File

@ -0,0 +1,25 @@
# ***************************************************************
# * 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.
# ***************************************************************
#Thu Aug 07 12:00:41 BST 2008
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
org.eclipse.jdt.core.compiler.compliance=1.5
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.5

View File

@ -0,0 +1,23 @@
# ***************************************************************
# * 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.
# ***************************************************************
#Thu Aug 07 12:00:50 BST 2008
eclipse.preferences.version=1
pluginProject.equinox=false
pluginProject.extensions=false
resolve.requirebundle=false

Some files were not shown because too many files have changed in this diff Show More