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-2007 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.xml.schema.abe.wizard;
043:
044: import java.awt.Component;
045: import java.io.File;
046: import java.util.HashMap;
047: import java.util.HashSet;
048: import java.util.Iterator;
049: import java.util.List;
050: import java.util.Set;
051: import javax.swing.event.ChangeEvent;
052: import javax.swing.event.ChangeListener;
053: import org.netbeans.modules.xml.axi.AXIModelFactory;
054: import org.netbeans.modules.xml.axi.Element;
055: import org.netbeans.modules.xml.axi.SchemaGenerator;
056: import org.netbeans.modules.xml.axi.SchemaGeneratorFactory;
057: import org.netbeans.modules.xml.schema.model.SchemaModel;
058: import org.openide.WizardDescriptor;
059: import org.openide.filesystems.FileObject;
060: import org.openide.filesystems.FileUtil;
061: import org.openide.util.HelpCtx;
062: import org.openide.util.NbBundle;
063: import org.openide.util.RequestProcessor;
064:
065: public class SchemaTransformPatternSelection implements
066: WizardDescriptor.Panel, ChangeListener {
067: private static final long serialVersionUID = 1L;
068: private static final long file_size_warning = 512 * 1024L;
069:
070: SchemaGenerator.Pattern inferedPattern;
071:
072: RequestProcessor.Task transformTask = null;
073:
074: //a cache to store previous hints
075: HashMap<SchemaGenerator.Pattern, SchemaGeneratorFactory.TransformHint> hintMap = new HashMap<SchemaGenerator.Pattern, SchemaGeneratorFactory.TransformHint>();
076:
077: List<Element> ges = null;
078:
079: /**
080: * The visual component that displays this panel. If you need to access the
081: * component from this class, just use getComponent().
082: */
083: private SchemaTransformPatternSelectionUI component;
084:
085: private WizardDescriptor wizard = null;
086:
087: public SchemaTransformPatternSelection(
088: SchemaGenerator.Pattern inferedPattern) {
089: this .inferedPattern = inferedPattern;
090: }
091:
092: // Get the visual component for the panel. In this template, the component
093: // is kept separate. This can be more efficient: if the wizard is created
094: // but never displayed, or not all panels are displayed, it is better to
095: // create only those which really need to be visible.
096: public Component getComponent() {
097: if (component == null) {
098: component = new SchemaTransformPatternSelectionUI(
099: inferedPattern);
100: component.addChangeListener(this );
101:
102: //Error or Warnings that need to be shown on first time of
103: //invocation is not feasible due to NB code WizardDescriptor.java:548
104: //ie., wizardPanel is not yet initialized. So workaround is to try
105: //invoking isValid() after 200 msec.
106: transformTask = RequestProcessor.getDefault().create(
107: new Runnable() {
108: public void run() {
109: try {
110: isValid();
111: } catch (Throwable th) {
112: transformTask.schedule(300);
113: }
114: }
115: });
116: transformTask.schedule(200);
117: }
118: return component;
119: }
120:
121: public HelpCtx getHelp() {
122: return new HelpCtx(SchemaTransformPatternSelection.class); //NOI18n
123: }
124:
125: public boolean isValid() {
126: SchemaModel sm = (SchemaModel) wizard
127: .getProperty(SchemaTransformWizard.SCHEMA_MODEL_KEY);
128: SchemaGenerator.Pattern inferedPattern = (SchemaGenerator.Pattern) wizard
129: .getProperty(SchemaTransformWizard.INFERED_DESIGN_PATTERN_KEY);
130: SchemaGenerator.Pattern selectedPattern = (SchemaGenerator.Pattern) wizard
131: .getProperty(SchemaTransformWizard.SELECTED_DESIGN_PATTERN_KEY);
132: if (inferedPattern != null && selectedPattern != null) {
133: SchemaGeneratorFactory.TransformHint hint = SchemaGeneratorFactory.TransformHint.OK;
134: try {
135: if (ges == null) //cache this for later use in this panel
136: ges = SchemaGeneratorFactory.getDefault()
137: .findMasterGlobalElements(
138: AXIModelFactory.getDefault()
139: .getModel(sm));
140: hint = canTransformSchema(sm, inferedPattern,
141: selectedPattern, ges);
142: } catch (Throwable th) {
143: hint = SchemaGeneratorFactory.TransformHint.INVALID_SCHEMA;
144: }
145: if (hint != SchemaGeneratorFactory.TransformHint.OK) {
146: if (inferedPattern == selectedPattern
147: || hint == SchemaGeneratorFactory.TransformHint.INVALID_SCHEMA
148: || hint == SchemaGeneratorFactory.TransformHint.NO_GLOBAL_ELEMENTS
149: || hint == SchemaGeneratorFactory.TransformHint.GLOBAL_ELEMENTS_HAVE_NO_CHILD_ELEMENTS
150: || hint == SchemaGeneratorFactory.TransformHint.GLOBAL_ELEMENTS_HAVE_NO_CHILD_ATTRIBUTES
151: || hint == SchemaGeneratorFactory.TransformHint.GLOBAL_ELEMENTS_HAVE_NO_CHILD_ELEMENTS_AND_ATTRIBUTES
152: || hint == SchemaGeneratorFactory.TransformHint.GLOBAL_ELEMENTS_HAVE_NO_GRAND_CHILDREN) {
153: setErrorMessage(
154: "MSG_SchemaTransform_Error_"
155: + hint.toString(),
156: new Object[] { NbBundle
157: .getMessage(
158: SchemaTransformPatternSelectionUI.class,
159: "LBL_SchemaTransform_"
160: + selectedPattern
161: .toString()) });
162: return false;
163: } else if (hint == SchemaGeneratorFactory.TransformHint.CANNOT_REMOVE_GLOBAL_ELEMENTS) {
164: SchemaGenerator.Pattern other = SchemaGenerator.Pattern.SALAMI_SLICE;
165: if (inferedPattern == SchemaGenerator.Pattern.SALAMI_SLICE)
166: other = SchemaGenerator.Pattern.GARDEN_OF_EDEN;
167: setErrorMessage(
168: "MSG_SchemaTransform_Error_"
169: + hint.toString(),
170: new Object[] {
171: NbBundle
172: .getMessage(
173: SchemaTransformPatternSelectionUI.class,
174: "LBL_SchemaTransform_"
175: + selectedPattern
176: .toString()),
177: NbBundle
178: .getMessage(
179: SchemaTransformPatternSelectionUI.class,
180: "LBL_SchemaTransform_"
181: + other
182: .toString()) });
183: return false;
184: } else {
185: String perfWarning = "";
186: if (canAddPerformanceWarning()) {
187: perfWarning = NbBundle
188: .getMessage(
189: SchemaTransformPatternSelectionUI.class,
190: "MSG_SchemaTransform_Warning_BIG_SCHEMA");
191: }
192: String warningMsgKey = "MSG_SchemaTransform_Warning_"
193: + hint.toString();
194: setErrorMessage(
195: warningMsgKey,
196: new Object[] {
197: NbBundle
198: .getMessage(
199: SchemaTransformPatternSelectionUI.class,
200: "LBL_SchemaTransform_"
201: + selectedPattern
202: .toString()),
203: perfWarning });
204: return true;
205: }
206: }
207: }
208: setErrorMessage(null);
209: return true;
210: // If it depends on some condition (form filled out...), then:
211: // return someCondition();
212: // and when this condition changes (last form field filled in...) then:
213: // fireChangeEvent();
214: // and uncomment the complicated stuff below.
215: }
216:
217: private SchemaGeneratorFactory.TransformHint canTransformSchema(
218: final SchemaModel sm,
219: final SchemaGenerator.Pattern inferedPattern,
220: final SchemaGenerator.Pattern selectedPattern,
221: List<Element> ges) {
222: SchemaGeneratorFactory.TransformHint hint = hintMap
223: .get(selectedPattern);
224: if (hint == null) {
225: hint = SchemaGeneratorFactory.getDefault()
226: .canTransformSchema(sm, inferedPattern,
227: selectedPattern, ges);
228: hintMap.put(selectedPattern, hint);
229: }
230: return hint;
231: }
232:
233: private void setErrorMessage(String key) {
234: if (key == null) {
235: setLocalizedErrorMessage(""); // NOI18N
236: } else {
237: setLocalizedErrorMessage(NbBundle.getMessage(
238: SchemaTransformPatternSelection.class, key)); // NOI18N
239: }
240: }
241:
242: private void setErrorMessage(String key, Object[] params) {
243: if (key == null) {
244: setLocalizedErrorMessage(""); // NOI18N
245: } else {
246: setLocalizedErrorMessage(NbBundle.getMessage(
247: SchemaTransformPatternSelection.class, key, params)); // NOI18N
248: }
249: }
250:
251: private boolean canAddPerformanceWarning() {
252: SchemaGenerator.Pattern selectedPattern = (SchemaGenerator.Pattern) wizard
253: .getProperty(SchemaTransformWizard.SELECTED_DESIGN_PATTERN_KEY);
254: if (selectedPattern != SchemaGenerator.Pattern.SALAMI_SLICE) {
255: return false;
256: }
257: SchemaModel sm = (SchemaModel) wizard
258: .getProperty(SchemaTransformWizard.SCHEMA_MODEL_KEY);
259: FileObject fo = (FileObject) sm.getModelSource().getLookup()
260: .lookup(FileObject.class);
261: if (fo == null)
262: return false;
263:
264: File file = FileUtil.toFile(fo);
265: if (file.length() > file_size_warning)
266: return true;
267:
268: return false;
269: }
270:
271: private void setLocalizedErrorMessage(String message) {
272: wizard.putProperty("WizardPanel_errorMessage", message); // NOI18N
273: }
274:
275: private final Set<ChangeListener> listeners = new HashSet<ChangeListener>(
276: 1);
277:
278: public final void addChangeListener(ChangeListener l) {
279: synchronized (listeners) {
280: listeners.add(l);
281: }
282: }
283:
284: public final void removeChangeListener(ChangeListener l) {
285: synchronized (listeners) {
286: listeners.remove(l);
287: }
288: }
289:
290: protected final void fireChangeEvent() {
291: Iterator<ChangeListener> it;
292: synchronized (listeners) {
293: it = new HashSet<ChangeListener>(listeners).iterator();
294: }
295: ChangeEvent ev = new ChangeEvent(this );
296: while (it.hasNext()) {
297: it.next().stateChanged(ev);
298: }
299: }
300:
301: // You can use a settings object to keep track of state. Normally the
302: // settings object will be the WizardDescriptor, so you can use
303: // WizardDescriptor.getProperty & putProperty to store information entered
304: // by the user.
305: public void readSettings(Object settings) {
306: wizard = (WizardDescriptor) settings;
307: Boolean isSingleGlobalElementSelected = (Boolean) wizard
308: .getProperty(SchemaTransformWizard.SINGLE_GLOBAL_ELEMENT_KEY);
309: if (isSingleGlobalElementSelected != null)
310: component
311: .setSingleGlobalElementSelected(isSingleGlobalElementSelected
312: .booleanValue());
313:
314: Boolean isTypeReuseSelected = (Boolean) wizard
315: .getProperty(SchemaTransformWizard.TYPE_REUSE_KEY);
316: if (isTypeReuseSelected != null)
317: component.setTypeReuseSelected(isTypeReuseSelected
318: .booleanValue());
319: }
320:
321: public void storeSettings(Object settings) {
322: wizard = (WizardDescriptor) settings;
323: wizard.putProperty(
324: SchemaTransformWizard.SINGLE_GLOBAL_ELEMENT_KEY,
325: Boolean.valueOf(component
326: .isSingleGlobalElementSelected()));
327: wizard.putProperty(SchemaTransformWizard.TYPE_REUSE_KEY,
328: Boolean.valueOf(component.isTypeReuseSelected()));
329: }
330:
331: public void stateChanged(ChangeEvent e) {
332: if (wizard != null)
333: wizard.putProperty(
334: SchemaTransformWizard.SELECTED_DESIGN_PATTERN_KEY,
335: component.getSelectedDesignPattern());
336: fireChangeEvent();
337: }
338:
339: }
|