mirror of https://github.com/apache/ant-ivy
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:
parent
5ca00743d5
commit
ec958b5f6e
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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/,\
|
||||
.
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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/,\
|
||||
.
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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 &Menu"
|
||||
id="sampleMenu">
|
||||
<separator
|
||||
name="sampleGroup">
|
||||
</separator>
|
||||
</menu>
|
||||
<action
|
||||
label="&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>
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
@ -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/
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>");
|
||||
}
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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 ::= <any string value that does not have ';' or ','>
|
||||
* 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('^');
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
// }
|
||||
|
||||
}
|
||||
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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 '&';
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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 '!';
|
||||
}
|
||||
}
|
||||
|
|
@ -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 '|';
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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() + "] ";
|
||||
}
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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()]);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
|
@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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())));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
Loading…
Reference in New Issue