001: /* -*- mode: Java; c-basic-offset: 2; -*- */
002:
003: /**
004: * LZX Library Compiler
005: */package org.openlaszlo.compiler;
006:
007: import java.io.*;
008: import java.util.*;
009: import org.jdom.Document;
010: import org.jdom.Element;
011: import org.openlaszlo.utils.ChainedException;
012: import org.openlaszlo.utils.FileUtils;
013: import org.apache.log4j.*;
014:
015: /** Compiler for <code>library</code> elements.
016: *
017: * @author Oliver Steele
018: */
019: class LibraryCompiler extends ToplevelCompiler {
020: final static String HREF_ANAME = "href";
021: final static String INCLUDES_ANAME = "includes";
022:
023: /** Logger
024: */
025: private static Logger mLogger = Logger
026: .getLogger(LibraryCompiler.class);
027:
028: LibraryCompiler(CompilationEnvironment env) {
029: super (env);
030: }
031:
032: static boolean isElement(Element element) {
033: return element.getName().equals("library");
034: }
035:
036: /** Return the library element and add the library to visited. If
037: * the library has already been visited, return null instead.
038: */
039: static Element resolveLibraryElement(File file,
040: CompilationEnvironment env, Set visited) {
041: try {
042: File key = file.getCanonicalFile();
043: if (!visited.contains(key)) {
044: mLogger.debug("Resolving: " + key);
045: visited.add(key);
046:
047: // If we're compiling a loadable library, add this to
048: // the list of library files which which have been
049: // included by loadable libraries, so we can warn on
050: // duplicates.
051: if (env.isImportLib()) {
052:
053: // compare this library file with the set of all known libraries that
054: // have been included in loadable modules. If this has been seen before,
055: // issue warning.
056: if (env.isImportLib()
057: && env.getLoadableImportedLibraryFiles()
058: .containsKey(key)) {
059: env
060: .warn(
061: /* (non-Javadoc)
062: * @i18n.test
063: * @org-mes="The library file \"" + p[0] + "\" included by loadable library \"" + p[1] + "\" was also included by another loadable library \"" + p[2] + "\". " + "This may lead to unexpected behavior, especially if the library defines new classes."
064: */
065: org.openlaszlo.i18n.LaszloMessages
066: .getMessage(
067: LibraryCompiler.class
068: .getName(),
069: "051018-77",
070: new Object[] {
071: file,
072: env
073: .getApplicationFile(),
074: env
075: .getLoadableImportedLibraryFiles()
076: .get(
077: key) }));
078: }
079:
080: env.getLoadableImportedLibraryFiles().put(key,
081: env.getApplicationFile());
082: }
083:
084: Element root = null;
085:
086: if (env.parsedLibraryCache.get(file) != null) {
087: root = (Element) env.parsedLibraryCache.get(file);
088: } else {
089: Document doc = env.getParser().parse(file, env);
090: root = doc.getRootElement();
091: env.parsedLibraryCache.put(file, root);
092: mLogger.debug("" + file + ": " + root
093: + " attributes: " + root.getAttributes());
094: // Look for and add any includes from a binary library
095: String includesAttr = root
096: .getAttributeValue(INCLUDES_ANAME);
097: File base = new File(Parser.getSourcePathname(root))
098: .getParentFile();
099: if (includesAttr != null) {
100: // This modularity sucks
101: Set binaryIncludes = env.getFileResolver()
102: .getBinaryIncludes();
103: for (StringTokenizer st = new StringTokenizer(
104: includesAttr); st.hasMoreTokens();) {
105: String name = FileUtils
106: .fromURLPath((String) st
107: .nextToken());
108: File canon = new File(base, name)
109: .getCanonicalFile();
110: mLogger.debug("binary include: " + canon);
111: visited.add(canon);
112: binaryIncludes.add(canon);
113: }
114: }
115: }
116: return root;
117: } else {
118: return null;
119: }
120: } catch (IOException e) {
121: throw new CompilationError(e);
122: }
123: }
124:
125: /** Return the resolved library element and add the library to visited.
126: * If the library has already been visited, return null instead.
127: */
128: static Element resolveLibraryElement(Element element,
129: CompilationEnvironment env, Set visited) {
130: String href = element.getAttributeValue(HREF_ANAME);
131: if (href == null) {
132: return element;
133: }
134: File file = env.resolveReference(element, HREF_ANAME, true);
135: return resolveLibraryElement(file, env, visited);
136: }
137:
138: public void compile(Element element) throws CompilationError {
139: element = resolveLibraryElement(element, mEnv, mEnv
140: .getImportedLibraryFiles());
141: if (element != null) {
142: super .compile(element);
143: }
144: }
145:
146: void updateSchema(Element element, ViewSchema schema, Set visited) {
147: element = resolveLibraryElement(element, mEnv, visited);
148: if (element != null) {
149: super .updateSchema(element, schema, visited);
150: // TODO [hqm 2005-02-09] can we compare any 'proxied' attribute here
151: // with the parent element (canvas) to warn if it conflicts.
152: }
153: }
154: }
155:
156: /**
157: * @copyright Copyright 2001-2007 Laszlo Systems, Inc. All Rights
158: * Reserved. Use is subject to license terms.
159: */
|