001: package net.refractions.udig.style.sld.editor;
002:
003: import java.util.Iterator;
004:
005: import net.refractions.udig.core.AdapterUtil;
006: import net.refractions.udig.core.internal.ExtensionPointProcessor;
007: import net.refractions.udig.core.internal.ExtensionPointUtil;
008: import net.refractions.udig.project.internal.Layer;
009: import net.refractions.udig.style.IStyleConfigurator;
010: import net.refractions.udig.style.sld.SLDPlugin;
011:
012: import org.eclipse.core.runtime.IConfigurationElement;
013: import org.eclipse.core.runtime.IExtension;
014: import org.eclipse.core.runtime.Plugin;
015: import org.eclipse.jface.action.Action;
016: import org.eclipse.jface.action.IAction;
017: import org.eclipse.jface.viewers.ISelection;
018: import org.eclipse.jface.viewers.IStructuredSelection;
019: import org.eclipse.swt.widgets.Shell;
020: import org.eclipse.ui.IViewActionDelegate;
021: import org.eclipse.ui.IViewPart;
022: import org.eclipse.ui.IWorkbenchWindow;
023: import org.eclipse.ui.IWorkbenchWindowActionDelegate;
024: import org.eclipse.ui.PlatformUI;
025:
026: /**
027: * Open the style editor dialog and add its pages
028: */
029: public class OpenStyleEditorAction extends Action implements
030: IWorkbenchWindowActionDelegate, IViewActionDelegate {
031: public static final String ATT_ID = "id"; //$NON-NLS-1$
032: public static final String ATT_CLASS = "class"; //$NON-NLS-1$
033: public static final String ATT_LABEL = "label"; //$NON-NLS-1$
034: public static final String ATT_REQUIRES = "requires"; //$NON-NLS-1$
035: public static final String STYLE_ID = "net.refractions.udig.style.sld"; //$NON-NLS-1$
036:
037: private Layer selectedLayer;
038:
039: private Plugin plugin;
040:
041: /**
042: * The workbench window; or <code>null</code> if this
043: * action has been <code>dispose</code>d.
044: */
045: private IWorkbenchWindow workbenchWindow;
046:
047: /**
048: * Create a new <code>OpenPreferenceAction</code>
049: * This default constructor allows the the action to be called from the welcome page.
050: */
051: public OpenStyleEditorAction() {
052: this (PlatformUI.getWorkbench().getActiveWorkbenchWindow());
053: }
054:
055: /**
056: * Create a new <code>OpenPreferenceAction</code> and initialize it
057: * from the given resource bundle.
058: * @param window
059: */
060: public OpenStyleEditorAction(IWorkbenchWindow window) {
061: super ();
062: if (window == null) {
063: throw new IllegalArgumentException();
064: }
065: this .workbenchWindow = window;
066: setActionDefinitionId("net.refractions.style.sld.editor"); //$NON-NLS-1$
067:
068: //setToolTipText(WorkbenchMessages.OpenPreferences_toolTip);
069: //window.getWorkbench().getHelpSystem().setHelp(this,
070: // IWorkbenchHelpContextIds.OPEN_PREFERENCES_ACTION);
071: }
072:
073: public void run(IAction action) {
074: if (workbenchWindow == null) {
075: return; // action has been disposed
076: }
077:
078: Shell shell = workbenchWindow.getShell();
079: //the page to select by default
080: String pageId = "simple"; //$NON-NLS-1$
081: //the filter to apply, if defined
082: //String[] displayedIds = null;
083:
084: final EditorPageManager[] manager = new EditorPageManager[] { new EditorPageManager(
085: '.') };
086:
087: ExtensionPointProcessor extProcPage = new ExtensionPointProcessor() {
088: public void process(IExtension extension,
089: IConfigurationElement element) throws Exception {
090: EditorNode node = null;
091:
092: boolean labelMissing = element.getAttribute(ATT_LABEL) == null;
093: String id = element.getAttribute(ATT_ID);
094: String requires = element.getAttribute(ATT_REQUIRES);
095: boolean classMissing = manager[0].getClassValue(
096: element, ATT_CLASS) == null;
097:
098: if (!(labelMissing || id == null || classMissing)) {
099: node = new EditorNode(id, element);
100: }
101: if (node == null)
102: return;
103:
104: if (requires != null
105: && !meetsRequirement(id, element, node)) {
106: return;
107: }
108:
109: manager[0].registerNode(node);
110: String category = node.getCategory();
111: if (category == null) {
112: manager[0].addToRoot(node);
113: } else {
114: EditorNode parent = null;
115: for (Iterator j = manager[0].getElements(
116: EditorPageManager.POST_ORDER).iterator(); j
117: .hasNext();) {
118: EditorNode pNode = (EditorNode) j.next();
119: if (category.equals(pNode.getId())) {
120: parent = pNode;
121: break;
122: }
123: }
124: if (parent == null) {
125: //TODO: log error
126: manager[0].addToRoot(node);
127: } else {
128: parent.add(node);
129: }
130: }
131: }
132: };
133: ExtensionPointUtil.process(plugin, StyleEditorPage.XPID,
134: extProcPage);
135:
136: ExtensionPointProcessor extProcConfigurator = new ExtensionPointProcessor() {
137: public void process(IExtension extension,
138: IConfigurationElement element) throws Exception {
139: EditorNode node = null;
140:
141: String id = element.getAttribute(ATT_ID);
142: String label = element.getAttribute(ATT_LABEL);
143: String requires = element.getAttribute(ATT_REQUIRES);
144: boolean classMissing = manager[0].getClassValue(
145: element, ATT_CLASS) == null;
146: if (label == null) {
147: SLDPlugin
148: .trace(
149: "StyleConfigurator extension point attribute 'label' not specified -- instance ignored: " + element.getClass(), null); //$NON-NLS-1$
150: return;
151: }
152: if (id == null) {
153: //if the optional id was not defined, skip
154: SLDPlugin
155: .trace(
156: "StyleConfigurator extension point attribute 'id' not specified -- skipped", null); //$NON-NLS-1$
157: return;
158: }
159: if (classMissing) {
160: SLDPlugin
161: .trace(
162: "StyleConfigurator extension point class could not be found: " + element.getClass(), null); //$NON-NLS-1$
163: return;
164: }
165: if (manager[0].hasNode(id)) {
166: SLDPlugin
167: .trace(
168: "Duplicate id found -- skipping '" + id + "' with label '" + label + "'", null); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
169: return;
170: }
171:
172: node = new EditorNode(id, element);
173:
174: if (node == null) {
175: SLDPlugin
176: .log(
177: "EditorNode creation failed in OpenStyleEditorAction", null); //$NON-NLS-1$
178: return;
179: }
180:
181: if (requires != null
182: && !meetsRequirement(id, element, node)) {
183: return;
184: }
185:
186: manager[0].registerNode(node);
187: String category = node.getCategory();
188: if (category == null) {
189: manager[0].addToRoot(node);
190: } else {
191: EditorNode parent = null;
192: for (Iterator j = manager[0].getElements(
193: EditorPageManager.POST_ORDER).iterator(); j
194: .hasNext();) {
195: EditorNode pNode = (EditorNode) j.next();
196: if (category.equals(pNode.getId())) {
197: parent = pNode;
198: break;
199: }
200: }
201: if (parent == null) {
202: //TODO: log error
203: manager[0].addToRoot(node);
204: } else {
205: parent.add(node);
206: }
207: }
208: }
209:
210: };
211: ExtensionPointUtil.process(plugin, IStyleConfigurator.XPID,
212: extProcConfigurator);
213:
214: StyleEditorDialog dialog = StyleEditorDialog.createDialogOn(
215: shell, pageId, selectedLayer, manager[0]);
216: //do filtering
217: //if (displayedIds != null)
218: // dialog.showOnly(displayedIds);
219: //open the dialog
220: dialog.open();
221: }
222:
223: boolean meetsRequirement(String id, IConfigurationElement element,
224: EditorNode node) {
225: String requires = element.getAttribute(ATT_REQUIRES);
226: try {
227: Object classInstance = EditorNode.createExtension(element,
228: EditorNode.ATT_CLASS);
229: // first try creating required class using extension classloading
230: // if this fails use the same classloader as the configurator
231: try {
232: Object requiredClass = element
233: .createExecutableExtension(ATT_REQUIRES);
234: if (!AdapterUtil.instance.canAdaptTo(requires,
235: selectedLayer, requiredClass.getClass()
236: .getClassLoader())) {
237: SLDPlugin.trace("skipped " + id, null); //$NON-NLS-1$
238: return false;
239: }
240:
241: } catch (Exception ce) {
242: // Failed trying to recover by using the configurators class's class loader
243: if (!AdapterUtil.instance.canAdaptTo(requires,
244: selectedLayer, classInstance.getClass()
245: .getClassLoader())) {
246: SLDPlugin.trace("skipped " + id, null); //$NON-NLS-1$
247: return false;
248: }
249: }
250: } catch (Exception e) {
251: SLDPlugin.log("extProcConfigurator skipped " //$NON-NLS-1$
252: + id + " (couldn't find " //$NON-NLS-1$
253: + requires + ")", null); //$NON-NLS-1$
254: return false;
255: }
256: return true;
257: }
258:
259: public void selectionChanged(IAction action, ISelection selection) {
260: if (selection.isEmpty()
261: || !(selection instanceof IStructuredSelection))
262: return;
263:
264: IStructuredSelection sselection = (IStructuredSelection) selection;
265: if (sselection.getFirstElement() instanceof Layer) {
266: selectedLayer = (Layer) sselection.getFirstElement();
267: }
268: }
269:
270: public void dispose() {
271: plugin = null;
272: workbenchWindow = null;
273: }
274:
275: public void init(IWorkbenchWindow window) {
276: }
277:
278: public void init(IViewPart view) {
279: }
280:
281: }
|