1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 import java.io.File;
25 import java.io.IOException;
26 import java.util.ArrayList;
27 import java.util.Hashtable;
28 import java.util.Enumeration;
29 import java.util.StringTokenizer;
30 
31 import com.sun.star.script.framework.container.ScriptEntry;
32 import com.sun.star.script.framework.container.ParcelDescriptor;
33 
34 import org.openoffice.idesupport.zip.ParcelZipper;
35 import org.openoffice.idesupport.filter.AllFilesFilter;
36 import com.sun.star.script.framework.container.XMLParserFactory;
37 import org.openoffice.idesupport.*;
38 
39 public class CommandLineTools {
40     private static final String PARCEL_XML_FILE =
41         ParcelZipper.PARCEL_DESCRIPTOR_XML;
42 
43     private static String officePath = null;
44 
main(String[] args)45     public static void main(String[] args) {
46         CommandLineTools driver = new CommandLineTools();
47         Command command = driver.parseArgs(args);
48 
49         // Get the URL for the Office DTD directory and pass it to the
50         // XMLParserFactory so that Office xml files can be parsed
51         if (officePath == null)
52         {
53             try {
54                 SVersionRCFile sv = SVersionRCFile.createInstance();
55                 if (sv.getDefaultVersion() != null)
56                 {
57                     officePath = sv.getDefaultVersion().getPath();
58                 }
59             }
60             catch (IOException ioe) {
61                 System.err.println("Error getting Office directory");
62             }
63         }
64 
65         if (officePath == null)
66         {
67             driver.fatalUsage("Error: Office Installation path not set");
68         }
69 
70         File officeDir = new File(officePath);
71         if (officeDir.exists() == false || officeDir.isDirectory() == false)
72         {
73             driver.fatalUsage(
74                 "Error: Office Installation path not valid: " + officePath);
75         }
76 
77         OfficeInstallation oi = new OfficeInstallation(officePath);
78         String url = oi.getURL("share/dtd/officedocument/1_0/");
79         XMLParserFactory.setOfficeDTDURL(url);
80 
81         if (command == null)
82             driver.printUsage();
83         else {
84             try {
85                 command.execute();
86             }
87             catch (Exception e) {
88                 driver.fatal("Error: " + e.getMessage());
89             }
90         }
91     }
92 
93     private interface Command {
execute()94         public void execute() throws Exception;
95     }
96 
printUsage()97     private void printUsage() {
98         System.out.println("java " + getClass().getName() + " -h " +
99             "prints this message");
100         System.out.println("java " + getClass().getName() +
101             " [-o Path to Office Installation] " +
102             "-d <script parcel zip file> " +
103             "<destination document or directory>");
104         System.out.println("java " + getClass().getName() +
105             " [-o Path to Office Installation] " +
106             "-g [parcel root directory] [options] [script names]");
107         System.out.println("options:");
108         System.out.println("\t[-l language[=supported extension 1[" +
109             File.pathSeparator + "supported extension 2]]]");
110         System.out.println("\t[-p name=value]");
111         System.out.println("\t[-v]");
112     }
113 
fatal(String message)114     private void fatal(String message) {
115         System.err.println(message);
116         System.exit(-1);
117     }
118 
fatalUsage(String message)119     private void fatalUsage(String message) {
120         System.err.println(message);
121         System.err.println();
122         printUsage();
123         System.exit(-1);
124     }
parseArgs(String[] args)125     private Command parseArgs(String[] args) {
126 
127         if (args.length < 1) {
128             return null;
129         }
130         else if (args[0].equals("-h")) {
131             return new Command() {
132                 public void execute() {
133                     printUsage();
134                 }
135             };
136         }
137 
138         int i = 0;
139 
140         if(args[0].equals("-o")) {
141             officePath = args[i+1];
142             i += 2;
143         }
144 
145         if(args[i].equals("-d")) {
146             if ((args.length - i) != 3)
147                 return null;
148             else
149                 return new DeployCommand(args[i+1], args[i+2]);
150         }
151         else if(args[i].equals("-g")) {
152 
153             if ((args.length - i) == 1)
154                 return new GenerateCommand(System.getProperty("user.dir"));
155 
156             GenerateCommand command;
157             i++;
158             if (!args[i].startsWith("-"))
159                 command = new GenerateCommand(args[i++]);
160             else
161                 command = new GenerateCommand(System.getProperty("user.dir"));
162 
163             for (; i < args.length; i++) {
164                 if (args[i].equals("-l")) {
165                     command.setLanguage(args[++i]);
166                 }
167                 else if (args[i].equals("-p")) {
168                     command.addProperty(args[++i]);
169                 }
170                 else if (args[i].equals("-v")) {
171                     command.setVerbose();
172                 }
173                 else {
174                     command.addScript(args[i]);
175                 }
176             }
177             return command;
178         }
179         return null;
180     }
181 
182     private static class GenerateCommand implements Command {
183 
184         private File basedir, contents, parcelxml;
185         private boolean verbose = false;
186         private String language = null;
187         private MethodFinder finder = null;
188         private ArrayList scripts = null;
189         private Hashtable properties = new Hashtable(3);
190 
191         public GenerateCommand(String basedir) {
192             this.basedir = new File(basedir);
193             this.contents = new File(basedir, ParcelZipper.CONTENTS_DIRNAME);
194             this.parcelxml = new File(contents, PARCEL_XML_FILE);
195         }
196 
197         public void setLanguage(String language) {
198             StringTokenizer tokenizer = new StringTokenizer(language, "=");
199             this.language = tokenizer.nextToken();
200 
201             if (this.language.toLowerCase().equals("java")) {
202                 this.finder = JavaFinder.getInstance();
203                 return;
204             }
205 
206             if (tokenizer.hasMoreTokens()) {
207                 String ext = (String)tokenizer.nextToken();
208                 String[] extensions;
209 
210                 if (ext.indexOf(File.pathSeparator) != -1) {
211                     tokenizer = new StringTokenizer(ext, File.pathSeparator);
212                     extensions = new String[tokenizer.countTokens()];
213                     int i = 0;
214 
215                     while(tokenizer.hasMoreTokens())
216                         extensions[i++] = (String)tokenizer.nextToken();
217                 }
218                 else {
219                     extensions = new String[1];
220                     extensions[0] = ext;
221                 }
222                 this.finder = new ExtensionFinder(this.language, extensions);
223             }
224         }
225 
226         public void addProperty(String prop) {
227             StringTokenizer tok = new StringTokenizer(prop, "=");
228 
229             if (tok.countTokens() != 2)
230                 return;
231 
232             String name = tok.nextToken();
233             String value = tok.nextToken();
234 
235             properties.put(name, value);
236         }
237 
238         public void setVerbose() {
239             verbose = true;
240         }
241 
242         public void addScript(String script) {
243             if (language == null)
244                 return;
245 
246             addScript(new ScriptEntry(language, script, script, basedir.getName()));
247         }
248 
249         public void addScript(ScriptEntry entry) {
250             if (scripts == null)
251                 scripts = new ArrayList(3);
252             scripts.add(entry);
253         }
254 
255         public void execute() throws Exception {
256 
257             if (basedir.isDirectory() != true) {
258                 throw new Exception(basedir.getName() + " is not a directory");
259             }
260             else if (contents.exists() != true) {
261                 throw new Exception(basedir.getName() +
262                     " does not contain a Contents directory");
263             }
264 
265             if (language == null && parcelxml.exists() == false) {
266                 throw new Exception(parcelxml.getName() + " not found and language " +
267                     "not specified");
268             }
269 
270             if (language != null && parcelxml.exists() == true) {
271                 ParcelDescriptor desc;
272                 String desclang = "";
273 
274                 desc = new ParcelDescriptor(parcelxml);
275                 desclang = desc.getLanguage().toLowerCase();
276 
277                 if (!desclang.equals(language.toLowerCase()))
278                     throw new Exception(parcelxml.getName() + " already exists, " +
279                         "and has a different language attribute: " +
280                         desc.getLanguage());
281             }
282 
283             if (language != null && scripts == null) {
284                 if (finder == null)
285                     throw new Exception("Extension list not specified for this language");
286 
287                 log("Searching for " + language + " scripts");
288 
289                 ScriptEntry[] entries = finder.findMethods(contents);
290                 for (int i = 0; i < entries.length; i++) {
291                     addScript(entries[i]);
292                     log("Found: " + entries[i].getLogicalName());
293                 }
294             }
295 
296             if (scripts != null) {
297                 if (scripts.size() == 0)
298                     throw new Exception("No valid scripts found");
299 
300                 ParcelDescriptor desc = new ParcelDescriptor(parcelxml, language);
301                 desc.setScriptEntries((ScriptEntry[])scripts.toArray(new ScriptEntry[0]));
302                 if (properties.size() != 0) {
303                     Enumeration enumer = properties.keys();
304 
305                     while (enumer.hasMoreElements()) {
306                         String name = (String)enumer.nextElement();
307                         String value = (String)properties.get(name);
308                         log("Setting property: " +  name + " to " + value);
309 
310                         desc.setLanguageProperty(name, value);
311                     }
312                 }
313                 desc.write();
314             }
315             else {
316                 if (parcelxml.exists() == false)
317                     throw new Exception("No valid scripts found");
318             }
319 
320             contents = new File(contents.getAbsolutePath());
321             String name = ParcelZipper.getParcelZipper().zipParcel(contents, AllFilesFilter.getInstance());
322             System.out.println(name + " generated");
323         }
324 
325         private void log(String message) {
326             if (verbose)
327                 System.out.println(message);
328         }
329     }
330 
331     private static class DeployCommand implements Command {
332 
333         File source, target;
334 
335         public DeployCommand(String source, String target) {
336             this.source = new File(source);
337             this.target = new File(target);
338         }
339 
340         public void execute() throws Exception {
341             ParcelZipper.getParcelZipper().deployParcel(source, target);
342             System.out.println(source.getName() +
343                 " successfully deployed to " + target.getAbsolutePath());
344         }
345     }
346 }
347