001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.project.ant;
043:
044: import java.awt.Frame;
045: import java.awt.event.WindowAdapter;
046: import java.awt.event.WindowEvent;
047: import java.io.CharArrayWriter;
048: import java.io.StringReader;
049: import java.util.logging.Level;
050: import java.util.logging.Logger;
051: import javax.swing.SwingUtilities;
052: import javax.xml.parsers.DocumentBuilderFactory;
053: import javax.xml.transform.Result;
054: import javax.xml.transform.Source;
055: import javax.xml.transform.Transformer;
056: import javax.xml.transform.TransformerFactory;
057: import javax.xml.transform.dom.DOMSource;
058: import javax.xml.transform.stream.StreamResult;
059: import javax.xml.transform.stream.StreamSource;
060: import org.openide.DialogDisplayer;
061: import org.openide.LifecycleManager;
062: import org.openide.NotifyDescriptor;
063: import org.openide.modules.ModuleInstall;
064: import org.openide.util.NbBundle;
065: import org.openide.windows.WindowManager;
066: import org.openide.xml.XMLUtil;
067: import org.w3c.dom.Document;
068: import org.xml.sax.InputSource;
069:
070: /**
071: * Checks for buggy versions of Xalan.
072: * @author Jan Lahoda
073: * @see "issue #70130"
074: */
075: public class AntProjectModule extends ModuleInstall {
076:
077: public @Override
078: void restored() {
079: super .restored();
080:
081: if (Boolean.getBoolean("netbeans.do.not.check.xalan")) // NOI18N
082: return;
083:
084: long start = System.currentTimeMillis();
085: boolean isBuggyXalan = checkForXalan();
086: long end = System.currentTimeMillis();
087: Logger.getLogger(AntProjectModule.class.getName()).log(
088: Level.FINE, "check for buggy xalan took %d",
089: end - start); // NOI18N
090:
091: if (isBuggyXalan) {
092: showWarning();
093: }
094: }
095:
096: private boolean checkForXalan() {
097: //check for a buggy xalan on the classpath and warn if necessary:
098: //try to load org.apache.xalan.Version class, OK if it does not exist:
099: try {
100: try {
101: XMLUtil.class.getClassLoader().loadClass(
102: "org.apache.xalan.Version"); // NOI18N
103: } catch (ClassNotFoundException ex) {
104: //ok, no xalan, everything is OK.
105: return false;
106: }
107: return !verifyWriterCorrect();
108: } catch (Exception ex) {
109: //should not happen, but probably OK:
110: Logger.getLogger(AntProjectModule.class.getName()).log(
111: Level.INFO, "Cannot run JAXP", ex);
112: } catch (Error e) {
113: Logger.getLogger(AntProjectModule.class.getName()).log(
114: Level.SEVERE, "Cannot run JAXP", e);
115: }
116:
117: return false;
118: }
119:
120: private boolean verifyWriterCorrect() throws Exception {
121: final String IDENTITY_XSLT_WITH_INDENT = "<xsl:stylesheet version='1.0' "
122: + // NOI18N
123: "xmlns:xsl='http://www.w3.org/1999/XSL/Transform' "
124: + // NOI18N
125: "xmlns:xalan='http://xml.apache.org/xslt' "
126: + // NOI18N
127: "exclude-result-prefixes='xalan'>"
128: + // NOI18N
129: "<xsl:output method='xml' indent='yes' xalan:indent-amount='4'/>"
130: + // NOI18N
131: "<xsl:template match='@*|node()'>" + // NOI18N
132: "<xsl:copy>" + // NOI18N
133: "<xsl:apply-templates select='@*|node()'/>" + // NOI18N
134: "</xsl:copy>" + // NOI18N
135: "</xsl:template>" + // NOI18N
136: "</xsl:stylesheet>"; // NOI18N
137: String data = "<root xmlns='root'/>"; // NOI18N
138: Document doc = DocumentBuilderFactory.newInstance()
139: .newDocumentBuilder().parse(
140: new InputSource(new StringReader(data)));
141: doc.getDocumentElement().appendChild(
142: doc.createElementNS("child", "child")); // NOI18N
143: Transformer t = TransformerFactory.newInstance()
144: .newTransformer(
145: new StreamSource(new StringReader(
146: IDENTITY_XSLT_WITH_INDENT)));
147: Source source = new DOMSource(doc);
148: CharArrayWriter output = new CharArrayWriter();
149: Result result = new StreamResult(output);
150: t.transform(source, result);
151:
152: output.close();
153:
154: String text = output.toString();
155:
156: return text.indexOf("\"child\"") != (-1)
157: || text.indexOf("'child'") != (-1); // NOI18N
158: }
159:
160: private void showWarning() {
161: NotifyDescriptor nd = new NotifyDescriptor.Message(NbBundle
162: .getMessage(AntProjectModule.class,
163: "LBL_Incompatible_Xalan")); // NOI18N
164:
165: DialogDisplayer.getDefault().notify(nd);
166:
167: //the IDE cannot be closed here (the window system data are corrupted then), wait until the main window appears
168: //and close then:
169: SwingUtilities.invokeLater(new Runnable() {
170: public void run() {
171: Frame f = WindowManager.getDefault().getMainWindow();
172:
173: if (f == null || f.isShowing()) {
174: LifecycleManager.getDefault().exit();
175: } else {
176: f.addWindowListener(new WindowAdapter() {
177: public @Override
178: void windowOpened(WindowEvent e) {
179: LifecycleManager.getDefault().exit();
180: }
181: });
182: }
183: }
184: });
185: }
186:
187: }
|