001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements.  See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership.  The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the
007     * "License"); you may not use this file except in compliance
008     * with the License.  You may obtain a copy of the License at
009     *
010     *  http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing,
013     * software distributed under the License is distributed on an
014     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     * KIND, either express or implied.  See the License for the
016     * specific language governing permissions and limitations
017     * under the License.
018     */
019    
020    package org.apache.geronimo.jaxws.builder;
021    
022    import java.io.BufferedReader;
023    import java.io.File;
024    import java.io.FileOutputStream;
025    import java.io.FileReader;
026    import java.io.FileWriter;
027    import java.io.InputStream;
028    import java.io.PrintWriter;
029    import java.io.StringReader;
030    import java.util.Properties;
031    
032    import javax.xml.parsers.DocumentBuilderFactory;
033    import javax.xml.transform.Transformer;
034    import javax.xml.transform.TransformerFactory;
035    import javax.xml.transform.dom.DOMSource;
036    import javax.xml.transform.stream.StreamResult;
037    import javax.xml.xpath.XPath;
038    import javax.xml.xpath.XPathConstants;
039    import javax.xml.xpath.XPathFactory;
040    
041    import org.w3c.dom.Document;
042    import org.w3c.dom.Element;
043    import org.w3c.dom.Node;
044    import org.w3c.dom.NodeList;
045    import org.xml.sax.InputSource;
046    
047    public class GShellCommandRegistration {
048        
049        private static String INDENT = "    ";
050               
051        private static boolean updateClassworlds(File classworldsFile, String classworlsTest, String classworlds) throws Exception {
052            boolean updated = checkClassworlds(classworldsFile, classworlsTest);
053            if (updated) {
054                return false;
055            }
056                                 
057            File tmpFile = new File(classworldsFile.getAbsolutePath() + ".tmp");
058            PrintWriter writer = new PrintWriter(new FileWriter(tmpFile));
059            BufferedReader reader = new BufferedReader(new FileReader(classworldsFile));
060            boolean inGShellSection = false;
061            String line = null;     
062            while( (line = reader.readLine()) != null) {
063                writer.println(line);
064                    
065                if (line.startsWith("[gshell]")) {                    
066                    inGShellSection = true;     
067                } else if (line.startsWith("[")) {
068                    inGShellSection = false;
069                } else if (inGShellSection) {
070                    if (!line.startsWith(INDENT)) {
071                        break;
072                    }
073                }
074            }
075                
076            if (inGShellSection) {
077                writer.println(INDENT + classworlds);
078            }
079                
080            while( (line = reader.readLine()) != null) {
081                writer.println(line);
082            }
083                
084            reader.close();
085            writer.close();
086                
087            switchFile(tmpFile, classworldsFile);
088            
089            return true;
090        }    
091        
092        private static boolean checkClassworlds(File classworldsFile, String classworlsTest) throws Exception {
093            BufferedReader reader = new BufferedReader(new FileReader(classworldsFile));
094            String line = null;
095            boolean matches = false;
096            while( (line = reader.readLine()) != null) {
097                if (line.matches(classworlsTest)) {
098                    matches = true;
099                    break;
100                }            
101            }
102            reader.close();
103            return matches;
104        }
105        
106        private static boolean updateLayout(File layoutFile, String layoutTest, String layout) throws Exception {  
107            
108            DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
109            Document layoutDocument = domFactory.newDocumentBuilder().parse(layoutFile);
110            
111            XPathFactory xpathFactory = XPathFactory.newInstance();
112            XPath xPath = xpathFactory.newXPath();
113            
114            Boolean updated = (Boolean)xPath.evaluate(layoutTest, layoutDocument, XPathConstants.BOOLEAN);
115            
116            if (updated.booleanValue()) {
117                return false;
118            }
119                                
120            Document doc = domFactory.newDocumentBuilder().parse(new InputSource(new StringReader(layout)));
121                
122            Element layoutElement = layoutDocument.getDocumentElement();
123            NodeList nodes = layoutElement.getElementsByTagName("nodes");
124            Node n = layoutDocument.importNode(doc.getDocumentElement(), true);
125            nodes.item(0).appendChild(n);
126                
127            TransformerFactory tFactory = TransformerFactory.newInstance();
128            Transformer transformer = tFactory.newTransformer();
129     
130            DOMSource source = new DOMSource(layoutDocument);
131            File tmpFile = new File(layoutFile.getAbsolutePath() + ".tmp");
132            FileOutputStream out = new FileOutputStream(tmpFile);
133            StreamResult result = new StreamResult(out);
134            transformer.transform(source, result);                    
135            out.close();
136                
137            switchFile(tmpFile, layoutFile);
138                
139            return true;        
140        }
141            
142        private static void switchFile(File tmpFile, File realFile) {
143            realFile.delete();
144            if (!tmpFile.renameTo(realFile)) {
145                throw new RuntimeException("Failed to rename " + tmpFile + " to " + realFile);
146            }
147        }
148        
149        public static void main(String [] args) throws Exception {
150            if (args.length != 2) {
151                throw new Exception("Syntax: GShellCommandRegistration <geronimo_home> <properties file>");
152            }
153            String baseDir = args[0];
154            String propsFile = args[1];
155            
156            ClassLoader loader = GShellCommandRegistration.class.getClassLoader();
157            InputStream in = loader.getResourceAsStream(propsFile);
158            
159            if (in == null) {
160                throw new Exception("Failed to load properties file: " + propsFile);
161            }
162                    
163            Properties p = new Properties();
164            p.load(in);
165                           
166            // update layout.xml
167            String layoutXPathTest = p.getProperty("layoutXPathTest");
168            String layoutEntry = p.getProperty("layoutEntry");
169            
170            if (layoutXPathTest != null && layoutEntry != null) {
171                File layoutFile = new File(baseDir, "etc/layout.xml");
172                if (updateLayout(layoutFile, layoutXPathTest, layoutEntry)) {
173                    System.out.println("Registered commands in layout.xml");
174                }
175            }
176            
177            // update gsh-classworlds.conf
178            String classworldsRegExTest = p.getProperty("classworldsRegExTest");
179            String classworldsEntry = p.getProperty("classworldsEntry");
180            if (classworldsRegExTest != null && classworldsEntry != null) {
181                File classworldsFile = new File(baseDir, "etc/gsh-classworlds.conf");            
182                if (updateClassworlds(classworldsFile, classworldsRegExTest, classworldsEntry)) {
183                    System.out.println("Updated gsh-classworlds.conf");
184                }
185            }
186                   
187        }
188         
189    }