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