001: package de.schlund.pfixcore.util;
002:
003: import java.io.File;
004: import java.util.Iterator;
005: import java.util.List;
006:
007: import javax.xml.parsers.DocumentBuilderFactory;
008:
009: import org.apache.log4j.xml.DOMConfigurator;
010: import org.w3c.dom.Document;
011: import org.w3c.dom.Element;
012: import org.w3c.dom.Node;
013: import org.w3c.dom.NodeList;
014:
015: import de.schlund.pfixxml.config.GlobalConfigurator;
016: import de.schlund.pfixxml.resources.DocrootResource;
017: import de.schlund.pfixxml.resources.ResourceUtil;
018: import de.schlund.pfixxml.util.XPath;
019: import de.schlund.pfixxml.util.Xml;
020: import de.schlund.pfixxml.util.XsltVersion;
021:
022: /**
023: * ImportText.java
024: *
025: * @author <a href="mailto:jtl@schlund.de">Jens Lautenbacher</a>
026: * @version 1.0
027: */
028:
029: public class ImportText {
030: private final static DocumentBuilderFactory dbfac = DocumentBuilderFactory
031: .newInstance();
032:
033: static {
034: dbfac.setNamespaceAware(true);
035: }
036:
037: public static void main(String[] args) throws Exception {
038: if (args.length != 2) {
039: System.err
040: .println("Usage: java de.schlund.pfixcore.util.ImportText <DOCROOT> <DUMP.XML>");
041: System.err
042: .println(" This will import all include parts from the given DUMP.XML file");
043: System.err
044: .println(" that must be given as a relative file name to DOCROOT.");
045: System.exit(0);
046: }
047: String docroot = args[0];
048: String dumpxml = args[1];
049: GlobalConfigurator.setDocroot(docroot);
050: ImportText trans = new ImportText();
051: DOMConfigurator.configure("core/conf/generator_quiet.xml");
052: trans.importList(dumpxml);
053: }
054:
055: /**
056: * This is the method that iterates over the list of USEDINCLUDE tags and imports
057: * its content into the right include file under the right part and theme.
058: * If the theme already exists, the content is replaced, otherwise a new theme is
059: * created.
060: * NOTE: For good performance, this method depends on the USEDINCLUDE tags
061: * to be grouped by the same PATH (aka, the same inlcude files) in the input file.
062: * The DumpText class takes care to dump the include parts ordered by include file,
063: * but depending on possible post processing, this may no longer be true.
064: * This method has only the simple optimization of serializing the changed file
065: * whenever a new include file is used, so having the parts to import in random order
066: * would result in serializing a changed include file after nearly every include part.
067: * @param dump - The file name of the file containing the include parts to be imported
068: * @throws Exception
069: */
070: public void importList(String dump) throws Exception {
071: Document dumpeddoc = Xml.parse(XsltVersion.XSLT1,
072: new File(dump));
073: List<Node> dumpedinclude = XPath.select(dumpeddoc,
074: "/dumpedincludeparts/USEDINCLUDE");
075:
076: String oldpath = null;
077: Document incdoc = null;
078: DocrootResource incfile = null;
079:
080: for (Iterator<Node> i = dumpedinclude.iterator(); i.hasNext();) {
081: Element usedinc = (Element) i.next();
082:
083: String path = usedinc.getAttribute("PATH");
084: // We serialize the old incdoc, because a new include file has to be parsed
085: incfile = ResourceUtil.getFileResourceFromDocroot(path);
086: if (incfile.exists()) {
087: if (!path.equals(oldpath) || incdoc == null) {
088: if (incdoc != null) {
089: Xml.serialize(incdoc, oldpath, false, true);
090: }
091: incdoc = Xml.parseMutable(incfile);
092: }
093: System.out.print(".");
094: handleInclude(incdoc, usedinc, path);
095: } else {
096: System.out.println("*** Missing include file " + path);
097: }
098: oldpath = path;
099: }
100: // Make sure to serialize the last incdoc
101: if (incdoc != null) {
102: Xml.serialize(incdoc, incfile, false, true);
103: }
104: System.out.println("\n");
105: }
106:
107: private void handleInclude(Document incdoc, Element usedinc,
108: String path) throws Exception {
109: String part = usedinc.getAttribute("PART");
110: String theme = usedinc.getAttribute("THEME");
111: String origcheck = usedinc.getAttribute("CHECK");
112: Element themeelem = (Element) XPath.selectNode(incdoc,
113: "/include_parts/part[@name = '" + part
114: + "']/theme[@name = '" + theme + "']");
115: Element themepart = (Element) XPath.selectNode(incdoc,
116: "/include_parts/part[@name = '" + part + "']");
117: if (themeelem != null) {
118: NodeList oldcontent = themeelem.getChildNodes();
119: int count = oldcontent.getLength();
120: for (int i = 0; i < count; i++) {
121: themeelem.removeChild(oldcontent.item(0));
122: }
123: } else if (themepart != null) {
124: themeelem = incdoc.createElement("theme");
125: themeelem.setAttribute("name", theme);
126: themepart.appendChild(incdoc.createTextNode(" "));
127: themepart.appendChild(themeelem);
128: themepart.appendChild(incdoc.createTextNode("\n"));
129: } else {
130: System.out.println("*** Didn't find part '" + part + "@"
131: + path + "'. Ignoring.");
132: return;
133: }
134: String check = DumpText.md5ForNode(usedinc);
135: if (check != null && !check.equals(origcheck)) {
136: System.out.print("\nInfo: CHECK differs for '" + theme
137: + "@" + part + "@" + path + "'");
138: }
139: NodeList content = usedinc.getChildNodes();
140: for (int i = 0; i < content.getLength(); i++) {
141: Node newnode = incdoc.importNode(content.item(i), true);
142: themeelem.appendChild(newnode);
143: }
144: }
145: }
|