Source code: org/enhydra/kelp/common/importer/ImportTool.java
1 /*
2 * Enhydra Java Application Server Project
3 *
4 * The contents of this file are subject to the Enhydra Public License
5 * Version 1.1 (the "License"); you may not use this file except in
6 * compliance with the License. You may obtain a copy of the License on
7 * the Enhydra web site ( http://www.enhydra.org/ ).
8 *
9 * Software distributed under the License is distributed on an "AS IS"
10 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
11 * the License for the specific terms governing rights and limitations
12 * under the License.
13 *
14 * The Initial Developer of the Enhydra Application Server is Lutris
15 * Technologies, Inc. The Enhydra Application Server and portions created
16 * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
17 * All Rights Reserved.
18 *
19 * Contributor(s):
20 *
21 */
22 package org.enhydra.kelp.common.importer;
23
24 // ToolBox imports
25 import org.enhydra.tool.ToolBoxInfo;
26 import org.enhydra.tool.common.FileUtil;
27 import org.enhydra.tool.common.PathHandle;
28 import org.enhydra.tool.common.ToolException;
29 import org.enhydra.tool.common.ExtensionFilter;
30 import org.enhydra.tool.common.TemplateTool;
31 import org.enhydra.tool.common.Template;
32 import org.enhydra.tool.common.Replacement;
33 import org.enhydra.tool.common.event.ProgressEvent;
34 import org.enhydra.tool.common.event.ProgressListener;
35
36 // Kelp imports
37 import org.enhydra.kelp.common.Constants;
38 import org.enhydra.kelp.common.KelpTool;
39 import org.enhydra.kelp.common.PathUtil;
40 import org.enhydra.kelp.common.ValidationException;
41 import org.enhydra.kelp.common.ValidationUtil;
42 import org.enhydra.kelp.common.map.Mapper;
43 import org.enhydra.kelp.common.node.OtterTemplateNode;
44 import org.enhydra.kelp.common.node.OtterNode;
45 import org.enhydra.kelp.common.node.OtterNodeFactory;
46 import org.enhydra.kelp.common.node.OtterDocumentNode;
47 import org.enhydra.kelp.common.wizard.deploy.DeployBuildTool;
48
49 // Standard imports
50 import java.io.BufferedReader;
51 import java.io.IOException;
52 import java.io.File;
53 import java.io.FileFilter;
54 import java.io.FileInputStream;
55 import java.io.FilenameFilter;
56 import java.io.FileReader;
57 import java.util.Enumeration;
58 import java.util.Properties;
59 import java.util.Vector;
60 import java.util.ResourceBundle;
61
62 /**
63 * Class declaration
64 *
65 * @author Paul Mahar
66 */
67 public class ImportTool extends KelpTool {
68
69 // string not to be resourced
70 static ResourceBundle res =
71 ResourceBundle.getBundle("org.enhydra.kelp.common.Res"); // nores
72 private final static String KELP_PROPERTIES = "kelp.properties"; // nores
73 private final static String PACKAGE_KEY = "package "; // nores
74 private final String[] IMAGE_TYPES = {
75 "gif", "jpg"
76 }; // nores
77
78 //
79 private ExtensionFilter optionFilter = null;
80 private ImportPaths paths = null;
81 private File[] inFiles = new File[0];
82
83 /**
84 * Method declaration
85 *
86 *
87 * @param javaSource
88 *
89 * @return
90 */
91 protected static String readPackage(File javaSource) {
92 BufferedReader in = null;
93 String line = null;
94 String pack = null;
95
96 try {
97 in = new BufferedReader(new FileReader(javaSource));
98 line = in.readLine();
99 while (line != null) {
100 line = line.trim();
101 if (line.startsWith(PACKAGE_KEY)) {
102 pack = line.substring(PACKAGE_KEY.length(),
103 line.indexOf(';'));
104 pack = pack.trim();
105 break;
106 } else {
107 line = in.readLine();
108 }
109 }
110 in.close();
111 } catch (java.io.IOException e) {
112 line = null;
113 }
114 if (!ValidationUtil.isJavaPackage(pack)) {
115 pack = null;
116 }
117 return pack;
118 }
119
120 /**
121 * Constructor declaration
122 */
123 public ImportTool() {
124 super();
125 optionFilter = new ExtensionFilter();
126 optionFilter.setDirectoryValid(false);
127 optionFilter.addExtension(Constants.TYPE_XMLC);
128 }
129
130 public ImportPaths getPaths() {
131 return paths;
132 }
133
134 public void setPaths(ImportPaths p) {
135 paths = p;
136 }
137
138 /**
139 *
140 */
141 public void addFiles(File[] files) {
142 OtterNodeFactory nodeFactory = null;
143 OtterDocumentNode node = null;
144 Mapper mapper = new Mapper(paths.getProject());
145 Vector templateVector = new Vector();
146 PathHandle inputPath = null;
147 String[] docTypes = new String[0];
148
149 docTypes = ToolBoxInfo.getSupportedDocTypes();
150 inputPath =
151 PathHandle.createPathHandle(paths.getProject().getDeployInputPath());
152 nodeFactory = paths.getProject().getNodeFactory();
153 for (int i = 0; i < files.length; i++) {
154 OtterNode folder = null;
155 PathHandle path = null;
156
157 path = PathHandle.createPathHandle(files[i]);
158 if (isIgnored(path.getPath())) {
159
160 // ignore it
161 } else {
162 folder = getFolder(nodeFactory, inputPath, files[i]);
163 if (path.hasExtension(Constants.TYPE_JAVA)) {
164 nodeFactory.createJavaFileNode(folder, path.getPath());
165
166 // Images
167 } else if (path.hasExtension(IMAGE_TYPES)) {
168 nodeFactory.createImageFileNode(folder, path.getPath());
169
170 // Document resources
171 } else if (path.hasExtension(docTypes)) {
172 node = nodeFactory.createDocumentNode(folder,
173 path.getPath());
174 setupDocumentNode(mapper, node);
175
176 // Templates
177 } else if (path.hasExtension(Constants.TYPE_IN)
178 && inputPath.parentOf(path)) {
179 OtterTemplateNode template = null;
180
181 template = nodeFactory.createTemplateNode(folder,
182 path.getPath());
183 template.setSelected(true);
184
185 // Other files xmlc, xml, makefile, rul, conf, etc.
186 } else {
187 nodeFactory.createTextFileNode(folder, path.getPath());
188 }
189 }
190 }
191 }
192
193 /**
194 * Method declaration
195 *
196 *
197 * @param project
198 */
199 public void importFilesFromRoot() {
200 importFiles(readFilesFromRoot());
201 }
202
203 /**
204 * Method declaration
205 *
206 *
207 * @param project
208 * @param files
209 */
210 public void importFiles(File[] files) {
211 setFresh(true);
212 inFiles = files;
213 if (getProgressListeners().length == 0) {
214 privateImport();
215 } else {
216 start();
217 }
218 }
219
220 private void privateImport() {
221 File[] files = inFiles;
222
223 inFiles = new File[0];
224 if (isFresh()) {
225 refreshProgress(10, res.getString("Preparing_import"));
226 preAdd();
227 }
228 if (isFresh()) {
229 refreshProgress(15, res.getString("Searching_templates"));
230 files = processConfInSource(files);
231 }
232 if (isFresh()) {
233 refreshProgress(20, res.getString("Importing_files"));
234 paths.initPackageMap(true);
235 }
236 if (isFresh()) {
237 addFiles(files);
238 }
239 if (isFresh()) {
240 refreshProgress(75, res.getString("Reading_makefiles"));
241 paths.getMakefileReader().updateProject();
242 }
243 if (isFresh()) {
244 refreshProgress(85, res.getString("Processing_input"));
245 postAdd();
246 }
247 if (isFresh()) {
248 refreshProgress(95, res.getString("Processing_templates"));
249 }
250 }
251
252 // Handle E3 newapp generated .conf templates that should
253 // be .conf.in
254 private File[] processConfInSource(File[] files) {
255 TemplateTool tool = null;
256 Template[] temps = new Template[1];
257 File dest = null;
258 PathHandle filePath = null;
259 PathHandle searchPath = null;
260
261 searchPath = PathHandle.createPathHandle(paths.getSourcePath()
262 + File.separator
263 + paths.getPackagePath());
264 for (int i = 0; i < files.length; i++) {
265 if (files[i] == null) {
266
267 // skip
268 } else {
269 filePath = PathHandle.createPathHandle(files[i]);
270 if (filePath.hasExtension(Constants.TYPE_CONF)
271 && searchPath.parentOf(filePath)) {
272 StringBuffer buf = new StringBuffer();
273
274 buf.append(filePath);
275 buf.append('.');
276 buf.append(Constants.TYPE_IN);
277 dest = new File(buf.toString());
278 if (!dest.exists()) {
279 try {
280 tool = new TemplateTool();
281 temps[0] = new Template(files[i], searchPath.getPath());
282 temps[0].setOutput(dest);
283 tool.setTemplates(temps);
284 files[i] = tool.createOutput()[0];
285 } catch (ToolException e) {
286 e.printStackTrace();
287 }
288 }
289 }
290 }
291 }
292 return files;
293 }
294
295 /**
296 *
297 */
298 private void preAdd() {
299 setupProjectSourcePath();
300 paths.initProject();
301 addKelpProperties();
302 }
303
304 /**
305 *
306 */
307 private void postAdd() {
308 DeployBuildTool deployTool = null;
309 OtterTemplateNode[] nodes = new OtterTemplateNode[0];
310
311 nodes = PathUtil.getInputTemplates(paths.getProject());
312 deployTool = new DeployBuildTool();
313 deployTool.setProject(paths.getProject());
314 deployTool.setNodes(nodes);
315 deployTool.setEcho(false);
316 deployTool.runInCurrentThread();
317
318 // Handler for Enhydra 3 style startup
319 boolean servlet = false;
320 String multi = new String();
321 String path = new String();
322
323 for (int i = 0; i < nodes.length; i++) {
324 path = nodes[i].getOutputFile().getAbsolutePath();
325 if (path.endsWith(Constants.FILE_SERVLET_CONF)) {
326 servlet = true;
327 } else if (path.endsWith(Constants.FILE_MULTISERVER_CONF)) {
328 multi = path;
329 }
330 }
331 if ((!servlet) && multi.length() > 0) {
332 paths.getProject().setDeployBootstrapPath(multi);
333 if (paths.getProject().isDeployStartupRun()) {
334 paths.getProject().configureRunClass();
335 }
336 }
337 }
338
339 private boolean isIgnored(String in) {
340 boolean ignore = false;
341 String path = in.toLowerCase().trim();
342
343 // conditional strings not to be translated
344 if (path.endsWith(".bak")) { // nores
345 ignore = true;
346 } else if (path.endsWith(".class")) { // nores
347 ignore = true;
348 } else if (path.endsWith("~")) { // nores
349 ignore = true;
350 } else if (path.endsWith(".jpr")) { // nores
351 ignore = true;
352 } else if (path.endsWith(".jpx")) { // nores
353 ignore = true;
354 } else if (path.endsWith(".jrl")) { // nores
355 ignore = true;
356 } else if (path.endsWith(".local")) { // nores
357 ignore = true;
358 } else if (path.endsWith("tbl")) { // nores
359 ignore = true;
360 } else if (path.endsWith("tmp")) { // nores
361 ignore = true;
362 } else if (path.endsWith(ImportTool.KELP_PROPERTIES.toLowerCase())) {
363 ignore = true;
364 } else if (path.indexOf("/cvs/") > -1) { // nores
365 ignore = true;
366 } else if (path.indexOf("/classes/") > -1) { // nores
367 ignore = true;
368 }
369 return ignore;
370 }
371
372 /**
373 *
374 */
375 private void addKelpProperties() {
376 StringBuffer filePath = new StringBuffer();
377 Properties properties = new Properties();
378 File file;
379 FileInputStream inStream;
380 Enumeration names;
381 String name;
382 String value;
383
384 filePath.append(new File(paths.getProject().getFilePath()).getParent());
385 filePath.append(File.separator);
386 filePath.append(KELP_PROPERTIES);
387 file = new File(filePath.toString());
388 if (file.exists()) {
389 try {
390 inStream = new FileInputStream(file);
391 properties.load(inStream);
392 names = properties.propertyNames();
393 while (names.hasMoreElements()) {
394 name = (String) names.nextElement();
395 value = properties.getProperty(name);
396 paths.getProject().setProperty(name, value);
397 }
398 inStream.close();
399 properties.clear();
400 file.delete();
401 } catch (Exception e) {
402
403 // non-fatal, report and continue
404 e.printStackTrace();
405 }
406 }
407 }
408
409 private String lookupSymbolicName(File sourceFile) {
410 MakefileData[] syms = new MakefileData[0];
411 String symName = new String();
412
413 syms = paths.getMakefileReader().getSymbolicMakefiles();
414 for (int i = 0; i < syms.length; i++) {
415 if (syms[i].containSourceDoc(sourceFile.getAbsolutePath())) {
416 File makeParent = new File(syms[i].getMakeParentPath());
417
418 symName = '.' + makeParent.getName();
419 break;
420 }
421 }
422 return symName;
423 }
424
425 /**
426 *
427 */
428 private OtterNode getFolder(OtterNodeFactory nodeFactory,
429 PathHandle inputPath,
430 File sourceFile) {
431
432 // Source path + app package + folder + java file name =
433 // java file absolute path.
434 OtterNode folderNode = paths.getProject();
435 String symName = new String();
436 String folderName = new String();
437 File projectFile = null;
438 PathHandle projectRoot = null;
439 PathHandle sourceRoot = null;
440 PathHandle packagePath = null;
441 PathHandle outputPath = null;
442
443 folderName = PathHandle.createPathString(sourceFile.getParent());
444 projectFile = new File(paths.getProject().getFilePath());
445 projectRoot = PathHandle.createPathHandle(projectFile.getParent());
446 sourceRoot = PathHandle.createPathHandle(paths.getSourcePath());
447 outputPath = PathHandle.createPathHandle(paths.getDeployRootPath());
448 packagePath = PathHandle.createPathHandle(sourceRoot.getPath()
449 + File.separator
450 + paths.getPackagePath());
451
452 // check if source is in symbolic makefiles
453 symName = lookupSymbolicName(sourceFile);
454
455 //
456 if (sourceRoot.parentOf(folderName)) {
457 if (packagePath.parentOf(folderName)) {
458 folderName =
459 folderName.substring(packagePath.getPath().length() + 1);
460 folderName = folderName.replace('/', '.');
461 } else {
462 folderName =
463 folderName.substring(sourceRoot.getPath().length() + 1);
464 }
465 folderNode = nodeFactory.createFolderNode(paths.getProject(),
466 folderName + symName);
467 } else if (projectRoot.parentOf(folderName)) {
468 folderName = folderName.substring(projectRoot.getPath().length()
469 + 1);
470 folderNode = nodeFactory.createFolderNode(paths.getProject(),
471 folderName + symName);
472 } else if (inputPath.parentOf(sourceFile)) {
473 folderName = Constants.DIR_INPUT;
474 folderNode = nodeFactory.createFolderNode(paths.getProject(),
475 folderName + symName);
476 } else if (outputPath.parentOf(sourceFile)) {
477 folderName = Constants.DIR_OUTPUT;
478 folderNode = nodeFactory.createFolderNode(paths.getProject(),
479 folderName + symName);
480
481 }
482 return folderNode;
483 }
484
485 /**
486 *
487 */
488 private void setupDocumentNode(Mapper mapper, OtterDocumentNode node) {
489 String sourcePath = node.getFilePath();
490 File sourceFile = null;
491 PathHandle parentPath = null;
492
493 parentPath = PathHandle.createPathHandle(paths.getSourcePath()
494 + File.separator
495 + paths.getPackagePath());
496 if ((sourcePath != null) && (parentPath.parentOf(sourcePath))) {
497 sourceFile = new File(sourcePath);
498 File file = null;
499 File[] list = new File[0];
500 String mappedPath = null;
501 String sourceName = null;
502 String javaName = null;
503
504 // if .xmlc options file found in mapped path,
505 // set xmlc file property
506 mappedPath = mapper.getMappedSourcePath(node);
507 file = new File(mappedPath);
508 file = file.getParentFile();
509 list = file.listFiles(optionFilter);
510 if ((list != null) && (list.length >= 1)) {
511 node.setXMLCOptionFilePath(list[0].getAbsolutePath());
512 }
513 list = file.listFiles(paths.getJavaFilter());
514 if (list != null) {
515 for (int i = 0; i < list.length; i++) {
516 sourceName = sourceFile.getName().toLowerCase();
517 sourceName =
518 sourceName.substring(0, sourceName.lastIndexOf('.'));
519 javaName = list[i].getName().toLowerCase();
520 if (javaName.startsWith(sourceName)) {
521 node.setSelected(true);
522 break;
523 }
524 }
525 }
526 if (!node.isSelected()) {
527 node.setStatic(true);
528 }
529
530 // if mapped package directory contains
531 // an xmlc file than set it as the
532 // String optionFilename = new String();
533 // node.setXMLCOptionFilename(optionFilename);
534 }
535 }
536
537 /**
538 *
539 */
540 private void setupProjectSourcePath() {
541 String[] path = paths.getProject().getSourcePathArray();
542 String[] newPath;
543 File current;
544 String[] javaList;
545 boolean javaFound = false;
546
547 for (int i = 0; i < path.length; i++) {
548 current = new File(path[i]);
549 javaList = current.list(new FilenameFilter() {
550
551 /**
552 * Method declaration
553 *
554 * @param dir
555 * @param name
556 *
557 * @return
558 */
559 public boolean accept(File dir, String name) {
560 return name.trim().toLowerCase().endsWith(Constants.TYPE_JAVA);
561 }
562
563 });
564 if ((javaList != null) && (javaList.length >= 1)) {
565 javaFound = true;
566 }
567 }
568 if (paths.getSourcePath().length() > 0) {
569 if (javaFound) {
570 newPath = new String[path.length + 1];
571 newPath[0] = paths.getSourcePath();
572 for (int i = 1; i < (path.length + 1); i++) {
573 newPath[i] = path[i - 1];
574 }
575 } else {
576 newPath = new String[1];
577 newPath[0] = paths.getSourcePath();
578 }
579 paths.getProject().setSourcePathArray(newPath);
580 }
581 }
582
583 /**
584 *
585 */
586 private File[] readFilesFromRoot() {
587 File[] files = new File[0];
588
589 if (paths.getRootPath() != null) {
590 File root = new File(paths.getRootPath());
591
592 files = readFiles(root);
593 }
594 return files;
595 }
596
597 /**
598 *
599 */
600 private File[] readFiles(File dir) {
601 File[] files = new File[0];
602 Vector fileVector = new Vector();
603 PathHandle classes = null;
604 PathHandle output = null;
605
606 classes = PathHandle.createPathHandle(paths.getClassOutputPath());
607 output = PathHandle.createPathHandle(paths.getDeployRootPath());
608 if (dir.isDirectory()) {
609 File[] list = dir.listFiles();
610
611 for (int i = 0; i < list.length; i++) {
612 if (list[i].isDirectory()) {
613 PathHandle cursor = null;
614
615 cursor = PathHandle.createPathHandle(list[i]);
616 if (classes.parentOf(cursor) || output.parentOf(cursor)) {
617
618 // skip over classes and output folders.
619 } else {
620 File[] subList = readFiles(list[i]);
621
622 for (int j = 0; j < subList.length; j++) {
623 fileVector.addElement(subList[j]);
624 }
625 }
626 } else if (list[i].isFile()) {
627 fileVector.addElement(list[i]);
628 }
629 }
630 }
631 if (fileVector.size() > 0) {
632 files = (File[]) fileVector.toArray(files);
633 }
634 return files;
635 }
636
637 public void run() {
638 setFresh(true);
639 refreshProgress(5, res.getString("Starting_import"));
640 privateImport();
641 if (isFresh()) {
642 refreshProgress(100, res.getString("Complete"));
643 }
644 }
645
646 }