/** * * Copyright 2003-2006 The Apache Software Foundation * * Licensed 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.geronimo.installer.processing; import org.apache.xerces.dom.TextImpl; import org.apache.xerces.parsers.DOMParser; import org.w3c.dom.Document; import org.w3c.dom.Text; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.Text; import java.lang.reflect.Method; import java.util.Vector; import java.io.File; import java.net.URL; import java.net.URLClassLoader; public class ConfigInstaller { // read the configure.xml // punch it into LocalConfigInstaller along with moving any // exes necessary (do proper chmods) protected static String installRoot = null; protected static String xmlName = null; // offset from installRoot protected static boolean fTrace = false; protected static URLClassLoader cl = null; protected static void initClassLoader() { Vector vjars = new Vector(); try { getJars( new File(installRoot), vjars ); } catch( Exception e ) { throw new RuntimeException( "unable to build list of jars for classloader" ); } Object ojars[] = vjars.toArray(); URL jars[] = new URL[ ojars.length ]; System.arraycopy( ojars, 0, jars, 0, ojars.length ); //for( int i = 0; i < jars.length; ++i ) { // System.out.println( "jar: " + jars[i].toString() ); //} cl = new URLClassLoader( jars, Thread.currentThread().getContextClassLoader() ); //System.out.println( "CL: " + cl ); } protected static void getJars( File baseDir, Vector jars ) throws Exception { File files[] = baseDir.listFiles(); for( int i = 0; i < files.length; ++i ) { if( files[ i ].isDirectory() ) { getJars( files[ i ], jars ); } else { String name = files[ i ].getCanonicalPath(); String nameUp = name.toUpperCase(); if( nameUp.endsWith( ".JAR" )) { jars.add( files[ i ].toURL() ); //System.out.println( "getJars: added " + files[ i ].toURL() ); } } } } // args: // installRoot // configuration xml (var/config/configure.xml) public static void main( String args[] ) { if( args.length >= 1 ) installRoot = args[0]; if( args.length >= 2 ) xmlName = args[1]; if( args.length >=3 ) { String parts[] = args[2].split("="); String varName = parts[0]; String value = parts[1]; System.out.println( "Found var: " + varName + " value = " + value ); if( varName.equalsIgnoreCase( "trace" )) { fTrace = false; if( value.equalsIgnoreCase( "true" )) fTrace = true; } } if( installRoot == null || xmlName == null ) { throw new RuntimeException( "ConfigInstaller: installRoot and xmlname required" ); } initClassLoader(); ConfigThread ct = new ConfigThread(); ct.setContextClassLoader( cl ); ct.start(); trace( "Joining ConfigThread..." ); try { ct.join(); } catch( Exception e ) { }; trace( "ConfigThread done." ); System.out.println( "Configuration complete." ); } protected static void trace( String output ) { if( fTrace ) { System.out.println( output ); } } } class ConfigWorker { protected Class installerCls = null; protected Object installerObj = null; protected Method execute = null; protected Method setTargetRoot = null; protected Method setTargetConfigStore = null; //"config-store" protected Method setTargetRepository = null; //"repository" protected Method setSourceRepository = null; //"${maven.repo.local}" protected Method setArtifact = null; protected DOMParser parser = null; protected boolean fTrace = false; protected void trace( String output ) { if( fTrace ) { System.out.println( output ); } } protected void doit( ClassLoader cl, Boolean fTrace ) { //ConfigWorker cw = new ConfigWorker(); this.fTrace = fTrace.booleanValue(); trace( ">ConfigWorker.doit()" ); if( init( cl ) && parse() ) { processXML(); } trace( "<ConfigWorker.doit()" ); } protected ConfigWorker() { } protected void initLocalConfigInstaller( ClassLoader cl ) { trace( ">ConfigWorker.initLocalConfigInstaller()" ); try { installerCls = cl.loadClass( "org.apache.geronimo.plugin.assembly.LocalConfigInstaller" ); } catch( Exception e ) { throw new RuntimeException( "Unable to load LocalConfigInstaller class" ); } try { execute = installerCls.getDeclaredMethod( "execute", null ); } catch( Exception e ) { throw new RuntimeException( "Unable to get method object \"execute\" from LocalConfigInstaller class" ); } try { setTargetRoot = installerCls.getSuperclass().getDeclaredMethod( "setTargetRoot", new Class[] { File.class } ); } catch( Exception e ) { throw new RuntimeException( "Unable to get method object \"setTargetRoot\" from LocalConfigInstaller class" ); } try { setTargetConfigStore = installerCls.getSuperclass().getDeclaredMethod( "setTargetConfigStore", new Class[] { String.class } ); } catch( Exception e ) { throw new RuntimeException( "Unable to get method object \"setTargetConfigStore\" from LocalConfigInstaller class" ); } try { setTargetRepository = installerCls.getSuperclass().getDeclaredMethod( "setTargetRepository", new Class[] { String.class } ); } catch( Exception e ) { throw new RuntimeException( "Unable to get method object \"setTargetRepository\" from LocalConfigInstaller class" ); } try { setSourceRepository = installerCls.getSuperclass().getDeclaredMethod( "setSourceRepository", new Class[] { File.class } ); } catch( Exception e ) { throw new RuntimeException( "Unable to get method object \"setSourceRepository\" from LocalConfigInstaller class" ); } try { setArtifact = installerCls.getSuperclass().getDeclaredMethod( "setArtifact", new Class[] { String.class } ); } catch( Exception e ) { throw new RuntimeException( "Unable to get method object \"setArtifact\" from LocalConfigInstaller class" ); } try { installerObj = installerCls.newInstance(); } catch( Exception e ) { throw new RuntimeException( "Unable to create instanceof LocalConfigInstaller" ); } trace( "<ConfigWorker.initLocalConfigInstaller()" ); } protected boolean init(ClassLoader cl) { boolean fRet = true; trace( ">ConfigWorker.init()" ); initLocalConfigInstaller(cl); try { parser = new DOMParser(); } catch (Exception e) { System.err.println("error: Unable to instantiate XML parser"); fRet = false; } trace( "<ConfigWorker.init()" ); return fRet; } protected boolean parse() { boolean fRet = true; trace( ">ConfigWorker.parse()" ); try { parser.parse( ConfigInstaller.installRoot + '/' + ConfigInstaller.xmlName ); } catch( Exception e ) { System.err.println( "Exception while parsing: " + ConfigInstaller.installRoot + "/" + ConfigInstaller.xmlName ); fRet = false; } trace( "<ConfigWorker.parse()" ); return fRet; } protected void processXML() { trace( ">ConfigWorker.processXML()" ); Document doc = parser.getDocument(); Node node = doc.getDocumentElement(); processConfigurations(node); trace( "<ConfigWorker.processXML()" ); } protected int numElements = 0; protected boolean fSelected = false; protected String artifact = null; protected String executable = null; public void processConfigurations(Node node) { trace( ">ConfigWorker.processConfigurations()" ); // is there anything to do? if (node == null) { return; } String nodeName = node.getNodeName(); //System.out.println( "nodeName: " + nodeName ); if( nodeName.equalsIgnoreCase("configurations") == false ) { throw new RuntimeException("ConfigInstaller: Malformed XML. \"configurations\" element expected."); } Node child = node.getFirstChild(); while (child != null) { int nodeType = child.getNodeType(); if( nodeType == Node.ENTITY_REFERENCE_NODE || nodeType == Node.ENTITY_NODE || nodeType == Node.ELEMENT_NODE ) processConfiguration(child); child = child.getNextSibling(); } trace( "<ConfigWorker.processConfigurations()" ); } public void processConfiguration( Node node ) { trace( ">ConfigWorker.processConfiguration()" ); // is there anything to do? if (node == null) { return; } artifact = null; executable = null; fSelected = false; String nodeName = node.getNodeName(); //System.out.println( "nodeName: " + nodeName ); if( nodeName.equalsIgnoreCase("configuration") == false ) { throw new RuntimeException("ConfigInstaller: Malformed XML. \"configuration\" element expected. (" + nodeName + ")" ); } Node child = node.getFirstChild(); while (child != null) { int nodeType = child.getNodeType(); if( nodeType != Node.ENTITY_REFERENCE_NODE && nodeType != Node.ENTITY_NODE && nodeType != Node.ELEMENT_NODE ) { child = child.getNextSibling(); continue; } nodeName = child.getNodeName(); if( nodeName.equalsIgnoreCase( "selected" )) { Text text = (Text)child.getFirstChild(); fSelected = false; if( text.getNodeValue().trim().equalsIgnoreCase( "true" )) { fSelected = true; } } else if( nodeName.equalsIgnoreCase( "executable" )) { Text text = (Text)child.getFirstChild(); executable = text.getNodeValue(); executable = executable.trim(); } else if( nodeName.equalsIgnoreCase( "artifact" )) { Text text = (Text)child.getFirstChild(); artifact = text.getNodeValue(); artifact = artifact.trim(); } else { throw new RuntimeException( "ConfigInstaller: Malformed XML. Element of type \"selected\" or \"executable\" or \"artifact\" expected. (" + nodeName + ")" ); } child = child.getNextSibling(); } if( fSelected ) { //System.out.println( "Install config. A: " + artifact + " E: " + executable ); doInstall(); } else { //System.out.println( "NO Install config. A: " + artifact + " E: " + executable ); } trace( "<ConfigWorker.processConfiguration()" ); } protected void doInstall() { trace( ">ConfigWorker.doInstall()" ); //System.out.println( "doInstall()" ); doMethod( setTargetConfigStore, new Object[] { "config-store" } ); doMethod( setTargetRepository, new Object[] { "repository" } ); doMethod( setArtifact, new Object[] { artifact } ); doMethod( setTargetRoot, new Object[] { new File( ConfigInstaller.installRoot ) } ); doMethod( setSourceRepository, new Object[] { new File( ConfigInstaller.installRoot + "/repository" ) } ); doMethod( execute, new Object[] { } ); trace( "<ConfigWorker.doInstall()" ); } protected void doMethod( Method m, Object[] parms ) { trace( ">ConfigWorker.doMethod()" ); try { m.invoke( installerObj, parms ); } catch( Exception e ) { System.err.println( e.getMessage() ); e.printStackTrace(); throw new RuntimeException( "Exception while executing: LocalConfigInstaller." + m.getName() ); } trace( "<ConfigWorker.doMethod()" ); } } class ConfigThread extends Thread { public void run() { //ConfigWorker.doit(); <-- this would be nice, but... // using reflection is required to get the classloader override to work Class cwc = null; Object cw = null; ClassLoader cl = Thread.currentThread().getContextClassLoader(); //System.out.println( "CL: " + cl.toString() ); Boolean fTrace = new Boolean( ConfigInstaller.fTrace ); try { cwc = cl.loadClass( "org.apache.geronimo.installer.processing.ConfigWorker" ); cw = cwc.newInstance(); } catch( Exception e ) { e.printStackTrace(); throw new RuntimeException( "Unable to load ConfigWorker class" ); } Method doit = null; try { doit = cwc.getDeclaredMethod( "doit", new Class[] { ClassLoader.class, Boolean.class } ); } catch( Exception e ) { e.printStackTrace(); throw new RuntimeException( "Unable to load ConfigWorker doit method" ); } try { doit.invoke( cw, new Object[] { cl, fTrace } ); } catch( Exception e ) { e.printStackTrace(); throw new RuntimeException( "Exception while executing: ConfigWorker.doit()" ); } } }