<parent>\r
<groupId>org.argeo.slc.maven</groupId>\r
<artifactId>slc-maven</artifactId>\r
- <version>0.1.1</version>\r
+ <version>0.1.2</version>\r
<relativePath>..</relativePath>\r
</parent>\r
<artifactId>maven-argeo-osgi-plugin</artifactId>\r
- <version>0.1.4</version>\r
+ <version>0.1.5</version>\r
<packaging>maven-plugin</packaging>\r
<name>Argeo OSGi Plugin</name>\r
\r
</plugins>\r
</build>\r
<dependencies>\r
+ <dependency>\r
+ <groupId>org.argeo.slc.maven</groupId>\r
+ <artifactId>org.argeo.slc.maven.plugin</artifactId>\r
+ <version>0.1.2</version>\r
+ </dependency>\r
<dependency>\r
<groupId>org.apache.maven</groupId>\r
<artifactId>maven-project</artifactId>\r
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+import java.util.jar.Attributes;
import java.util.jar.Manifest;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
*/
public abstract class AbstractBundlesPackagerMojo extends AbstractOsgiMojo {
- /**
- * The maven project.
- *
- * @parameter expression="${project}"
- * @required
- * @readonly
- */
- protected MavenProject project;
-
/**
* Directory of the simple bundles
*
File destFile = new File(packagedBundlesDir.getPath()
+ File.separator + artifactId + ".jar");
try {
+ String manifestStr = FileUtils.readFileToString(manifestFile);
+ char lastChar = manifestStr.charAt(manifestStr.length() - 1);
+ if (lastChar != '\n')
+ throw new RuntimeException(
+ "Manifest "
+ + manifestFile
+ + " is not valid, it does not end with and endline character.");
+
Manifest manifest = readManifest(manifestFile);
// Symbolic name
String symbolicNameMf = manifest.getMainAttributes().getValue(
manifest.getMainAttributes().putValue("Bundle-Version",
newVersionMf);
+ manifest.getMainAttributes().put(
+ Attributes.Name.MANIFEST_VERSION, "1.0");
+
Artifact artifact = artifactFactory.createBuildArtifact(project
.getGroupId(), artifactId, newVersionArt, "jar");
BundlePackage bundlePackage = new BundlePackage(artifact, dir,
- manifest, destFile);
+ new Manifest(manifest), destFile);
list.add(bundlePackage);
} catch (Exception e) {
throw new MojoExecutionException("Could not analyze " + dir, e);
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.project.MavenProject;
/**
* Factorize common configuration
*/
public abstract class AbstractOsgiMojo extends AbstractMojo {
+ /**
+ * The maven project.
+ *
+ * @parameter expression="${project}"
+ * @required
+ * @readonly
+ */
+ protected MavenProject project;
+
/**
* List of Remote Repositories used by the resolver
*
--- /dev/null
+package org.argeo.slc.maven.plugins.osgi;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
+import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.argeo.slc.maven.plugin.SystemCall;
+
+/**
+ * @goal equinox-exec
+ * */
+public class EquinoxExecMojo extends AbstractOsgiMojo {
+ /**
+ * Used to look up Artifacts in the remote repository.
+ *
+ * @parameter expression=
+ * "${component.org.apache.maven.artifact.resolver.ArtifactResolver}"
+ * @required
+ * @readonly
+ */
+ protected org.apache.maven.artifact.resolver.ArtifactResolver resolver;
+
+ /**
+ * Used to look up Artifacts in the remote repository.
+ *
+ * @parameter expression=
+ * "${component.org.apache.maven.artifact.factory.ArtifactFactory}"
+ * @required
+ * @readonly
+ */
+ protected org.apache.maven.artifact.factory.ArtifactFactory factory;
+
+ /** @component */
+ private ArtifactMetadataSource artifactMetadataSource;
+
+ /**
+ * Equinox artifact id
+ *
+ * @parameter expression="${equinoxArtifactId}"
+ * default-value="org.eclipse.osgi"
+ * @required
+ */
+ protected String equinoxArtifactId;
+
+ /**
+ * OSGIBoot artifact id
+ *
+ * @parameter expression="${osgiBootArtifactId}"
+ * default-value="org.argeo.slc.osgiboot"
+ * @required
+ */
+ protected String osgiBootArtifactId;
+
+ /**
+ * Java executable
+ *
+ * @parameter expression="${jvm}" default-value="java"
+ * @required
+ */
+ protected String jvm;
+
+ /**
+ * JVM arguments
+ *
+ * @parameter alias="${jvmArgs}"
+ */
+ protected String[] jvmArgs;
+
+ protected String[] defaultJvmArgs = { "-Xmx256m" };
+
+ /**
+ * Equinox args
+ *
+ * @parameter alias="${args}"
+ */
+ protected String[] args;
+
+ protected String[] defaultArgs = { "-clean", "-console", "-configuration",
+ "conf" };
+
+ /**
+ * Execution directory
+ *
+ * @parameter expression="${execDir}"
+ * @required
+ */
+ protected File execDir;
+
+ public void execute() throws MojoExecutionException, MojoFailureException {
+ try {
+ Artifact equinoxArtifact = null;
+ Artifact osgiBootArtifact = null;
+
+ Set artifacts = project.createArtifacts(this.factory, null, null);
+
+ ArtifactResolutionResult arr = resolver.resolveTransitively(
+ artifacts, project.getArtifact(), local, remoteRepos,
+ artifactMetadataSource, null);
+ // Order, just for display
+ Set dependencies = new TreeSet(new Comparator() {
+ public int compare(Object o1, Object o2) {
+ Artifact a1 = (Artifact) o1;
+ Artifact a2 = (Artifact) o2;
+
+ if (!a1.getGroupId().equals(a2.getGroupId()))
+ return a1.getGroupId().compareTo(a2.getGroupId());
+ else
+ return a1.getArtifactId().compareTo(a2.getArtifactId());
+ }
+ });
+ dependencies.addAll(arr.getArtifacts());
+
+ StringBuffer osgiLocations = new StringBuffer();
+ List bundleArtifacts = new ArrayList();
+ boolean first = true;
+ // Set dependencies = project.getArtifacts();
+ for (Iterator it = dependencies.iterator(); it.hasNext();) {
+ Artifact depArtifact = (Artifact) it.next();
+ System.out.println(depArtifact.getGroupId() + ":"
+ + depArtifact.getArtifactId() + ":"
+ + depArtifact.getType() + ":"
+ + depArtifact.getVersion() + " ("
+ + depArtifact.getFile() + ")");
+ if (depArtifact.getArtifactId().equals(equinoxArtifactId))
+ equinoxArtifact = depArtifact;
+ else if (depArtifact.getArtifactId().equals(osgiBootArtifactId))
+ osgiBootArtifact = depArtifact;
+ else {
+ bundleArtifacts.add(depArtifact);
+
+ if (first)
+ first = false;
+ else
+ osgiLocations.append(File.pathSeparatorChar);
+ osgiLocations.append(depArtifact.getFile()
+ .getCanonicalPath()
+ .replace(File.separatorChar, '/'));
+ }
+ }
+
+
+ // Set defaults
+ if(jvmArgs==null)
+ jvmArgs=defaultJvmArgs;
+ if(args==null)
+ args=defaultArgs;
+
+
+ List cmdList = new ArrayList();
+ cmdList.add(jvm);
+ cmdList.addAll(Arrays.asList(jvmArgs));
+ cmdList.add("-Dosgi.bundles="
+ + osgiBootArtifact.getFile().getCanonicalPath() + "@start");
+ cmdList.add("-Dslc.osgi.locations=" + osgiLocations);
+ cmdList.add("-jar");
+ cmdList.add(equinoxArtifact.getFile().getCanonicalPath());
+ cmdList.addAll(Arrays.asList(args));
+
+ String[] cmd = (String[])cmdList.toArray(new String[0]);
+
+// String cmdOld = jvm + " " + jvmArgs + " " + "-Dosgi.bundles="
+// + osgiBootArtifact.getFile().getCanonicalPath() + "@start "
+// + "-Dslc.osgi.locations=" + osgiLocations + " -jar "
+// + equinoxArtifact.getFile().getCanonicalPath() + " " + args;
+ for(int i=0;i<cmd.length;i++)
+ System.out.print(cmd[i]);
+ System.out.print('\n');
+
+ SystemCall systemCall = new SystemCall(execDir.getCanonicalPath(),
+ cmd, true);
+ systemCall.run();
+
+ } catch (Exception e) {
+ throw new MojoExecutionException("Cannot execute Equinox", e);
+ }
+
+ }
+}
// Write manifest
FileOutputStream out = new FileOutputStream(manifestFile);
- bundlePackage.getManifest().getMainAttributes().put(
- Attributes.Name.MANIFEST_VERSION, "1.0");
- System.out.println("# BUNDLE "
+ System.out.println("\n# BUNDLE "
+ bundlePackage.getArtifact().getArtifactId());
Attributes mainAttrs = bundlePackage.getManifest()
.getMainAttributes();
<parent>\r
<groupId>org.argeo.slc.maven</groupId>\r
<artifactId>slc-maven</artifactId>\r
- <version>0.1.1</version>\r
+ <version>0.1.2</version>\r
<relativePath>..</relativePath>\r
</parent>\r
<artifactId>maven-argeo-qooxdoo-plugin</artifactId>\r
- <version>0.8.1.4</version>\r
+ <version>0.8.1.5</version>\r
<packaging>maven-plugin</packaging>\r
<name>Argeo Qooxdoo Plugin</name>\r
\r
<dependency>\r
<groupId>org.argeo.slc.maven</groupId>\r
<artifactId>org.argeo.slc.maven.plugin</artifactId>\r
+ <version>0.1.2</version>\r
</dependency>\r
<dependency>\r
<groupId>org.apache.maven</groupId>\r
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java"/>
<classpathentry kind="src" path="src/main/resources"/>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
<parent>\r
<groupId>org.argeo.slc.maven</groupId>\r
<artifactId>slc-maven</artifactId>\r
- <version>0.1.1</version>\r
+ <version>0.1.2</version>\r
<relativePath>..</relativePath>\r
</parent>\r
<artifactId>org.argeo.slc.maven.plugin</artifactId>\r
+ <version>0.1.2</version>\r
<packaging>jar</packaging>\r
<name>Argeo Maven Plugin Development Support</name>\r
\r
<groupId>org.codehaus.plexus</groupId>\r
<artifactId>plexus-archiver</artifactId>\r
</dependency>\r
+ <dependency>\r
+ <groupId>commons-io</groupId>\r
+ <artifactId>commons-io</artifactId>\r
+ </dependency>\r
+\r
</dependencies>\r
</project>
--- /dev/null
+package org.argeo.slc.maven.plugin;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.util.List;
+
+import org.apache.commons.io.IOUtils;
+
+public class SystemCall implements Runnable {
+ private String execDir;
+
+ private String cmd = null;
+ private String[] command = null;
+
+ private boolean synchronous = true;
+ private boolean captureStdIn = false;
+
+ public SystemCall() {
+
+ }
+
+ public SystemCall(String execDir, String cmd, boolean captureStdIn) {
+ super();
+ this.execDir = execDir;
+ this.cmd = cmd;
+ this.synchronous = true;
+ this.captureStdIn = captureStdIn;
+ }
+
+ public SystemCall(String execDir, String[] command, boolean captureStdIn) {
+ super();
+ this.execDir = execDir;
+ this.command = command;
+ this.synchronous = true;
+ this.captureStdIn = captureStdIn;
+ }
+
+ public void run() {
+ try {
+ // Execution directory
+ File dir = null;
+ if (execDir != null) {
+ // Replace '/' by local file separator, for portability
+ execDir.replace('/', File.separatorChar);
+ dir = new File(execDir).getCanonicalFile();
+ }
+
+ final Process process;
+
+ if (cmd != null) {
+ process = Runtime.getRuntime().exec(cmd, null, dir);
+ } else if (command != null) {
+ process = Runtime.getRuntime().exec(command, null, dir);
+ ;
+ } else {
+ throw new RuntimeException("No command specified");
+ }
+
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+
+ public void run() {
+ if (process != null) {
+ try {
+ process.exitValue();
+ } catch (Exception e) {
+ process.destroy();
+ System.err.println("Killed process " + process);
+ }
+ }
+ }
+ });
+
+ // Manage standard streams
+ StreamReaderThread stdOutThread = new StreamReaderThread(process
+ .getInputStream(), false);
+ stdOutThread.start();
+ // TODO: understand why streams are not properly flushed
+ StreamReaderThread stdErrThread = new StreamReaderThread(process
+ .getInputStream(), false);
+ stdErrThread.start();
+ if (captureStdIn)
+ new StdInThread(process.getOutputStream()).start();
+
+ // Wait for the end of the process
+ if (synchronous) {
+ int exitCode = process.waitFor();
+ if (exitCode != 0) {
+ Thread.sleep(5000);// leave the process a chance to log
+ System.err.println("Process return exit code " + exitCode);
+ }
+ } else {
+ // asynchronous: return
+ }
+ } catch (Exception e) {
+ throw new RuntimeException("Could not execute command " + cmd, e);
+ }
+
+ }
+
+ /**
+ * Shortcut method returning the current exec dir if the specified one is
+ * null.
+ */
+ private String getUsedDir(File dir) {
+ if (dir == null)
+ return System.getProperty("user.dir");
+ else
+ return dir.getPath();
+ }
+
+ public void setCmd(String command) {
+ this.cmd = command;
+ }
+
+ public void setExecDir(String execdir) {
+ this.execDir = execdir;
+ }
+
+ public void setCommand(String[] command) {
+ this.command = command;
+ }
+
+ protected synchronized void write(String str, boolean isErr) {
+ if (isErr) {
+ System.err.print(str);
+ System.err.flush();
+ } else {
+ System.out.print(str);
+ System.out.flush();
+ }
+ notifyAll();
+ }
+
+ protected class StreamReaderThread extends Thread {
+ private final InputStream stream;
+ private final boolean isErr;
+
+ public StreamReaderThread(InputStream stream, boolean isErr) {
+ this.stream = stream;
+ this.isErr = isErr;
+ }
+
+ public void run() {
+ // BufferedReader in = null;
+ InputStreamReader isr = null;
+ try {
+ isr = new InputStreamReader(stream);
+ int c;
+ StringBuffer buf = new StringBuffer(256);
+ char lastCr = '\n';
+ while ((c = isr.read()) != -1) {
+ char cr = (char) c;
+
+ buf.append(cr);
+
+ boolean write = false;
+ if (lastCr == '>' && cr == ' ')
+ write = true;
+ else if (cr == '\n')
+ write = true;
+
+ lastCr = cr;
+ if (write) {
+ write(buf.toString(), isErr);
+ buf = new StringBuffer(256);
+ }
+
+ // if (isErr) {
+ // System.err.print(cr);
+ // if (cr == '\n' || cr == '>')
+ // System.err.flush();
+ // } else {
+ // System.out.print(cr);
+ // if (cr == '\n' || cr == '>')
+ // System.out.flush();
+ // }
+ }
+ // String line = null;
+ // while ((line = in.readLine()) != null) {
+ // stdOutCallback(line);
+ // System.out.
+ // }
+ } catch (IOException e) {
+ // catch silently
+ // because the other methods
+ // to check whether the stream
+ // is closed would probably
+ // be to costly
+ } finally {
+ if (synchronous)
+ IOUtils.closeQuietly(isr);
+ }
+ }
+ }
+
+ protected class StdInThread extends Thread {
+ private final OutputStream stream;
+
+ public StdInThread(OutputStream stream) {
+ this.stream = stream;
+ }
+
+ public void run() {
+ // BufferedReader in = null;
+ // Writer out = null;
+ InputStreamReader isr = null;
+ try {
+ // out = new OutputStreamWriter(stream);
+ isr = new InputStreamReader(System.in);
+ int c;
+ while ((c = isr.read()) != -1) {
+ stream.write(c);
+ stream.flush();
+ }
+
+ /*
+ * in = new BufferedReader(new InputStreamReader(System.in));
+ * String line = null; while ((line = in.readLine()) != null) {
+ * out.write(line); out.write("\n"); out.flush(); }
+ */
+ } catch (IOException e) {
+ throw new RuntimeException("Could not write to stdin stream", e);
+ } finally {
+ if (synchronous) {
+ IOUtils.closeQuietly(isr);
+ // IOUtils.closeQuietly(in);
+ // IOUtils.closeQuietly(out);
+ }
+ }
+ }
+
+ }
+}