001: package net.refractions.udig.style.sld.editor;
002:
003: import java.io.ByteArrayInputStream;
004: import java.io.IOException;
005: import java.io.InputStream;
006: import java.io.UnsupportedEncodingException;
007: import java.util.List;
008:
009: import javax.xml.transform.TransformerException;
010:
011: import net.refractions.udig.style.sld.SLDPlugin;
012: import net.refractions.udig.style.sld.internal.Messages;
013: import net.refractions.udig.ui.graphics.SLDs;
014:
015: import org.eclipse.jface.dialogs.MessageDialog;
016: import org.eclipse.swt.SWT;
017: import org.eclipse.swt.custom.SashForm;
018: import org.eclipse.swt.events.FocusEvent;
019: import org.eclipse.swt.events.FocusListener;
020: import org.eclipse.swt.events.ModifyEvent;
021: import org.eclipse.swt.events.ModifyListener;
022: import org.eclipse.swt.events.SelectionEvent;
023: import org.eclipse.swt.events.SelectionListener;
024: import org.eclipse.swt.graphics.Cursor;
025: import org.eclipse.swt.layout.GridData;
026: import org.eclipse.swt.layout.GridLayout;
027: import org.eclipse.swt.widgets.Button;
028: import org.eclipse.swt.widgets.Composite;
029: import org.eclipse.swt.widgets.Display;
030: import org.eclipse.swt.widgets.Label;
031: import org.eclipse.swt.widgets.Shell;
032: import org.eclipse.swt.widgets.Text;
033: import org.eclipse.ui.PlatformUI;
034: import org.geotools.event.GTEvent;
035: import org.geotools.styling.SLDParser;
036: import org.geotools.styling.SLDTransformer;
037: import org.geotools.styling.Style;
038: import org.geotools.styling.StyleFactory;
039: import org.geotools.styling.StyleFactoryFinder;
040: import org.geotools.styling.StyledLayerDescriptor;
041:
042: public class StyleXMLPage extends StyleEditorPage {
043:
044: SashForm sash;
045: Text sldTextBox;
046: Text errorsTextBox;
047: SLDValidator validator;
048: Label validateStatus;
049: Button validateButton;
050:
051: boolean validSLD = true;
052: boolean dirty = false;
053:
054: @Override
055: public void createPageContent(Composite parent) {
056: Composite comp = new Composite(parent, SWT.NONE);
057: GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
058: comp.setLayoutData(gd);
059: comp.setLayout(new GridLayout(3, false));
060:
061: sash = new SashForm(comp, SWT.VERTICAL);
062: gd = new GridData(SWT.FILL, SWT.FILL, true, true);
063: gd.widthHint = parent.getBounds().x;
064: gd.heightHint = parent.getBounds().y;
065: gd.horizontalSpan = 3;
066: sash.setLayoutData(gd);
067:
068: sldTextBox = new Text(sash, SWT.BORDER | SWT.MULTI
069: | SWT.H_SCROLL | SWT.V_SCROLL);
070: sldTextBox.setEditable(true);
071: sldTextBox.addModifyListener(new ModifyListener() {
072:
073: public void modifyText(ModifyEvent e) {
074: dirty = true;
075: validateStatus
076: .setText(Messages.StyleEditor_xml_validation_needed);
077: validateButton.setEnabled(true);
078: }
079:
080: });
081:
082: sldTextBox.addFocusListener(new FocusListener() {
083: public void focusGained(FocusEvent e) {
084: }
085:
086: public void focusLost(FocusEvent e) {
087: // if (isValid())
088: // updateSLD();
089: }
090: });
091:
092: errorsTextBox = new Text(sash, SWT.BORDER | SWT.MULTI
093: | SWT.H_SCROLL | SWT.V_SCROLL);
094: errorsTextBox.setVisible(false);
095: errorsTextBox.setEditable(false);
096:
097: validateStatus = new Label(comp, SWT.LEFT);
098: validateStatus
099: .setText(Messages.StyleEditor_xml_validation_needed);
100: gd = new GridData(SWT.LEFT, SWT.BOTTOM, true, false);
101: validateStatus.setLayoutData(gd);
102:
103: //TODO: add code for style reset
104: // Button resetButton = new Button(comp, SWT.RIGHT);
105: // resetButton.setText("Reset");
106: // gd = new GridData(SWT.RIGHT, SWT.NONE, false, false);
107: // resetButton.setLayoutData(gd);
108: // resetButton.addSelectionListener(new SelectionListener() {
109: //
110: // public void widgetSelected( SelectionEvent e ) {
111: //
112: // }
113: //
114: // public void widgetDefaultSelected( SelectionEvent e ) {
115: // widgetSelected(e);
116: // }
117: //
118: // });
119:
120: validateButton = new Button(comp, SWT.RIGHT);
121: validateButton.setText(Messages.StyleEditor_xml_validate);
122: gd = new GridData(SWT.RIGHT, SWT.NONE, false, false);
123: validateButton.setLayoutData(gd);
124: validateButton.addSelectionListener(new SelectionListener() {
125:
126: public void widgetSelected(SelectionEvent e) {
127: validateSLD();
128: if (validSLD) {
129: updateSLD();
130: }
131: }
132:
133: public void widgetDefaultSelected(SelectionEvent e) {
134: widgetSelected(e);
135: }
136:
137: });
138:
139: styleChanged(null);
140: }
141:
142: @Override
143: public boolean performCancel() {
144: return true;
145: }
146:
147: @Override
148: public String getErrorMessage() {
149: if (!validSLD) {
150: return Messages.StyleEditor_xml_invalid;
151: }
152: return null;
153: }
154:
155: public void validateSLD() {
156: Cursor waitCursor = new Cursor(Display.getCurrent(),
157: SWT.CURSOR_WAIT);
158: setDisplayCursor(waitCursor);
159:
160: validateButton.setEnabled(false);
161: validateStatus
162: .setText(Messages.StyleEditor_xml_validation_progress);
163: String xml = sldTextBox.getText();
164: dirty = false;
165: if (xml.length() == 0) {
166: validSLD = false;
167: sldTextBox.setText(styleToXML()); //revert to default
168: return;
169: }
170: InputStream is = getXMLasInputStream(xml, "UTF-8"); //$NON-NLS-1$
171: if (validator == null) {
172: validator = new SLDValidator();
173: }
174: Object result = validator
175: .validateSLD(is,
176: "http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd"); //$NON-NLS-1$
177:
178: if (result instanceof List) {
179: List errors = (List) result;
180: if (errors.size() == 0) {
181: validSLD = true;
182: this .errorsTextBox.setText(""); //$NON-NLS-1$
183: this .validateStatus
184: .setText(Messages.StyleEditor_xml_validation_success);
185: this .errorsTextBox.setVisible(false);
186: } else {
187: validSLD = false;
188: this .errorsTextBox.setText(SLDValidator
189: .getErrorMessage(is, errors));
190: this .validateStatus
191: .setText(Messages.StyleEditor_xml_validation_failure);
192: this .errorsTextBox.setVisible(true);
193: }
194: this .errorsTextBox.getParent().layout();
195: getContainer().updateMessage();
196: }
197: try {
198: is.close();
199: } catch (IOException e) {
200: // TODO Handle IOException
201: throw (RuntimeException) new RuntimeException()
202: .initCause(e);
203: } finally {
204: resetCursor(waitCursor);
205: }
206: if (dirty) {
207: validateButton.setEnabled(true);
208: validateStatus
209: .setText(Messages.StyleEditor_xml_validation_needed);
210: }
211: }
212:
213: private void resetCursor(Cursor c) {
214: setDisplayCursor(null);
215: c.dispose();
216: c = null;
217: }
218:
219: /**
220: * Sets the given cursor for all shells currently active
221: * for this window's display.
222: *
223: * @param c the cursor
224: */
225: private void setDisplayCursor(Cursor c) {
226: Shell[] shells = Display.getCurrent().getShells();
227: for (int i = 0; i < shells.length; i++)
228: shells[i].setCursor(c);
229: }
230:
231: @Override
232: public boolean isValid() {
233: return true;
234: }
235:
236: public boolean okToLeave() {
237: boolean readyToLeave = false;
238: if (validSLD || (!validSLD && dirty)) { //!dirty was a condition -- not required for the moment
239: readyToLeave = updateSLD();
240: }
241: if (readyToLeave) {
242: return true;
243: } else {
244: //inform the user that the SLD is invalid -- fix it or lose it
245: return MessageDialog.openQuestion(PlatformUI.getWorkbench()
246: .getActiveWorkbenchWindow().getShell(),
247: Messages.StyleEditor_xml_lose_changes_1,
248: Messages.StyleEditor_xml_lose_changes_2);
249: }
250: }
251:
252: public boolean performOk() {
253: return true;
254: }
255:
256: private String styleToXML() {
257: SLDTransformer aTransformer = new SLDTransformer();
258: aTransformer.setIndentation(StyleEditor.INDENT);
259: StyledLayerDescriptor sld = getSLD();
260: try {
261: return aTransformer.transform(sld);
262: } catch (TransformerException e) {
263: e.printStackTrace();
264: return null;
265: }
266: }
267:
268: private StyledLayerDescriptor XMLtoSLD(String xml) {
269: return XMLtoSLD(xml, "UTF-8"); //$NON-NLS-1$
270: }
271:
272: private StyledLayerDescriptor XMLtoSLD(String xml, String encoding) {
273: //save changes to style object
274: StyleFactory factory = StyleFactoryFinder.createStyleFactory();
275: InputStream is = getXMLasInputStream(xml, encoding);
276: if (is == null)
277: return null;
278: SLDParser stylereader = new SLDParser(factory, is);
279: StyledLayerDescriptor sld = stylereader.parseSLD();
280: return sld;
281: }
282:
283: private InputStream getXMLasInputStream(String xml, String encoding) {
284: InputStream is = null;
285: try {
286: is = new ByteArrayInputStream(xml.getBytes(encoding));
287: } catch (UnsupportedEncodingException e1) {
288: // TODO Handle UnsupportedEncodingException
289: throw (RuntimeException) new RuntimeException()
290: .initCause(e1);
291: }
292: return is;
293: }
294:
295: public void gotFocus() {
296: refresh();
297: dirty = false;
298: };
299:
300: @Override
301: public void styleChanged(GTEvent arg) {
302: dirty = true;
303: validateButton.setEnabled(true);
304: }
305:
306: public void refresh() {
307: String xmlOrig = sldTextBox.getText();
308: String xml = styleToXML();
309: if (xml != null && !xml.equals(xmlOrig)) {
310: sldTextBox.setText(xml);
311: validSLD = true;
312: dirty = true;
313: }
314: }
315:
316: private boolean updateSLD() {
317: //busy cursor
318: Cursor waitCursor = new Cursor(Display.getCurrent(),
319: SWT.CURSOR_WAIT);
320: setDisplayCursor(waitCursor);
321:
322: //generate the SLD
323: StyledLayerDescriptor sld = null;
324: Style style;
325: String xml = sldTextBox.getText();
326: if (xml == null) {
327: resetCursor(waitCursor);
328: return false;
329: }
330: try {
331: sld = XMLtoSLD(xml);
332: style = SLDs.getDefaultStyle(sld);
333: } catch (Exception e) {
334: SLDPlugin.log("SLD application failed", e);
335:
336: MessageDialog.openError(PlatformUI.getWorkbench()
337: .getActiveWorkbenchWindow().getShell(),
338: Messages.StyleEditor_xml_failure_1,
339: Messages.StyleEditor_xml_failure_2);
340:
341: validSLD = false;
342: resetCursor(waitCursor);
343: return false; //abort
344: }
345: //update the style / SLD
346: if (sld != null && style != null) {
347: validSLD = true;
348: setStyle(style);
349: resetCursor(waitCursor);
350: return true;
351: }
352: resetCursor(waitCursor);
353: return false;
354: }
355:
356: @Override
357: public void dispose() {
358: validator = null;
359: super .dispose();
360: }
361:
362: @Override
363: public String getLabel() {
364: return null;
365: }
366:
367: public boolean performApply() {
368: return updateSLD();
369: }
370:
371: }
|