Java tutorial
/* * uDig - User Friendly Desktop Internet GIS client * http://udig.refractions.net * (C) 2012, Refractions Research Inc. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * (http://www.eclipse.org/legal/epl-v10.html), and the Refractions BSD * License v1.0 (http://udig.refractions.net/files/bsd3-v10.html). */ package org.locationtech.udig.style.sld; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.SortedMap; import java.util.TreeMap; import org.locationtech.udig.core.internal.ExtensionPointProcessor; import org.locationtech.udig.core.internal.ExtensionPointUtil; import org.locationtech.udig.project.internal.Layer; import org.locationtech.udig.style.IStyleConfigurator; import org.locationtech.udig.style.sld.internal.Messages; import org.locationtech.udig.ui.graphics.SLDs; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtension; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.ActionContributionItem; import org.eclipse.jface.action.IContributionItem; import org.eclipse.jface.action.IMenuCreator; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Menu; import org.eclipse.ui.part.PageBook; import org.geotools.data.FeatureSource; import org.geotools.styling.Style; import org.geotools.styling.Symbolizer; import org.opengis.feature.simple.SimpleFeatureType; /** * An abstract class for style configurators intended for SLD style objects. * <p> * This class makes use of the sldEditorPart configuration point to produce several ViewParts * capable of editing individual Symbolizers. * </p> * <p> * * @author Justin Deoliveira, Refractions Research Inc. */ public class SLDConfigurator extends IStyleConfigurator { /** The content manager for modifying the style. * */ SLDContentManager sldContentManager; /** The editor book * */ PageBook editorBook; /** blank page * */ Composite blank; /** class 2 menu mapping * */ List<SLDEditorMenuAction> toolbarItems; /** This is the data structure the extention point is processed into */ SortedMap<Class, List<SLDEditorPart>> classToEditors; /** * Creates the configurator. */ public SLDConfigurator() { } /** * Checks if the layer is a feature layer or if the layer is a wms that supports post. */ public boolean canStyle(Layer layer) { if (layer.hasResource(FeatureSource.class)) return true; if (layer.hasResource(org.geotools.data.ows.Layer.class)) return true; return false; // TODO: check for wms supporting sld } /** * @see org.locationtech.udig.style.IStyleConfigurator#init(org.eclipse.ui.IViewSite) */ public void init() { sldContentManager = new SLDContentManager(); // process the extension point and add editors to the tool bar Comparator<Class> compare = new Comparator<Class>() { public int compare(Class a, Class b) { return a.getSimpleName().compareTo(b.getSimpleName()); } }; classToEditors = new TreeMap<Class, List<SLDEditorPart>>(compare); ExtensionPointProcessor p = new ExtensionPointProcessor() { public void process(IExtension ext, IConfigurationElement element) throws Exception { try { SLDEditorPart editor = (SLDEditorPart) element.createExecutableExtension("class"); //$NON-NLS-1$ editor.setPluginId(element.getNamespace()); editor.setLabel(element.getAttribute("label")); //$NON-NLS-1$ ImageDescriptor image = editor.createImageDescriptor(); if (image == null) { // TODO: set a default } else editor.setImageDescriptor(image); Class contentClass = editor.getContentType(); // aka symbolizer List<SLDEditorPart> list = classToEditors.get(contentClass); if (list == null) { list = new ArrayList<SLDEditorPart>(); classToEditors.put(contentClass, list); } list.add(editor); } catch (Exception e) { SLDPlugin.log(null, e); } } }; ExtensionPointUtil.process(SLDPlugin.getDefault(), SLDEditorPart.XPID, p); } /* * (non-Javadoc) * * @see org.locationtech.udig.style.IStyleConfigurator#createControl(org.eclipse.swt.widgets.Composite) */ public void createControl(Composite parent) { createToolbarItems(); // now we have toolbar items editorBook = new PageBook(parent, SWT.NONE); editorBook.setVisible(true); blank = new Composite(editorBook, SWT.NONE); editorBook.showPage(blank); for (List<SLDEditorPart> parts : classToEditors.values()) { for (SLDEditorPart part : parts) { try { part.createControl(editorBook); } catch (Throwable t) { SLDPlugin.log(null, t); } } } } /* * Called when new layer and blackbard values are available. <p> This provides update * information as a callback (rather than an event listener). </p> */ protected void refresh() { Layer layer = getLayer(); if (!canStyle(layer)) { throw new IllegalStateException("Hey I can't style " + layer); //$NON-NLS-1$ } // pull the sld style off the blackboard, and initialize the cm Style style = (Style) getStyleBlackboard().get(SLDContent.ID); // if no style information, create default if (style == null) { style = SLDContent.createDefaultStyle(); getStyleBlackboard().put(SLDContent.ID, style); } sldContentManager.init(SLDContent.getStyleBuilder(), style); // pull the feature type name out of the layer if (layer.getSchema() != null) { SimpleFeatureType featureType = layer.getSchema(); //set the name of the feature type style for the feature renderer String name = featureType.getName().getLocalPart(); sldContentManager.getDefaultFeatureTypeStyle().setFeatureTypeName(SLDs.GENERIC_FEATURE_TYPENAME); } // force the toolbar to refresh // IToolBarManager tbm = getViewSite().getActionBars().getToolBarManager(); tbm.markDirty(); tbm.update(true); getViewSite().getActionBars().updateActionBars(); for (IContributionItem item : tbm.getItems()) { ActionContributionItem action = (ActionContributionItem) item; action.getAction().setEnabled(action.getAction().isEnabled()); } // focus the active editor if any exisits SLDEditorPart editor = (SLDEditorPart) editorBook.getData(); List<Class> supported = SLD.getSupportedTypes(layer); if (editor != null) { if (supported.contains(editor.getContentType())) { initEditor(editor); editor.reset(); return; // current editor is still okay } } // if we get here the current editor wasn't applicable, show first that works for (Class type : classToEditors.keySet()) { if (!supported.contains(type)) continue; for (SLDEditorPart part : classToEditors.get(type)) { initEditor(part); // FIXME: we don't want the editor to have content it should not part.reset(); editorBook.setData(part); editorBook.showPage(part.getPage()); part.getPage().setVisible(true); return; } } editorBook.showPage(blank); } protected void createToolbarItems() { toolbarItems = new ArrayList<SLDEditorMenuAction>(); // FIXME! for (Class contentClass : classToEditors.keySet()) { List<SLDEditorPart> editors = classToEditors.get(contentClass); if (editors == null || editors.isEmpty()) { continue; // skip class with no editors } // add an editor for disable editors.add(new SLDDisableEditorPart(contentClass)); SLDEditorMenuAction action = new SLDEditorMenuAction(editors); // add to list of all toolbarItems.add(action); } // sort items so they dont randomly appear in the toolbar Collections.sort(toolbarItems); // add em here IToolBarManager tbm = getViewSite().getActionBars().getToolBarManager(); for (SLDEditorMenuAction item : toolbarItems) { tbm.add(item); } } /** * Sets the editor up for a reset(). Ensures the editor has content. */ void initEditor(SLDEditorPart editor) { // enable the symbolizer if necessary @SuppressWarnings("unchecked") Class<Symbolizer> symbolizerType = editor.getContentType(); Symbolizer content = sldContentManager.getSymbolizer(symbolizerType); if (content == null) { sldContentManager.addSymbolizer(symbolizerType); content = (Symbolizer) sldContentManager.getSymbolizer(symbolizerType); } editor.setStyleBuilder(sldContentManager.getStyleBuilder()); editor.setLayer(getLayer()); editor.setContent(content); } /** * Composite action made up of a drop down menu of actions. */ class SLDEditorMenuAction extends Action implements IMenuCreator, Comparable<SLDEditorMenuAction> { List<SLDEditorPart> editors; Menu menu; public SLDEditorMenuAction(List<SLDEditorPart> editors) { this.editors = editors; setMenuCreator(this); setImageDescriptor(editors.get(0).getImageDescriptor()); } public Class getContentType() { if (editors == null || editors.isEmpty()) return null; return editors.get(0).getContentType(); } public void dispose() { if (menu != null) { menu.dispose(); } } public Menu getMenu(Control parent) { if (menu != null) { menu.dispose(); } menu = new Menu(parent); for (SLDEditorPart editor : editors) { Action action = new SLDEditorAction(editor, this); addActionToMenu(menu, action); } return menu; } public Menu getMenu(Menu parent) { return null; } protected void addActionToMenu(Menu parent, Action action) { ActionContributionItem item = new ActionContributionItem(action); item.fill(parent, -1); } public int compareTo(SLDEditorMenuAction other) { return editors.get(0).getContentType().getName() .compareTo(other.editors.get(0).getContentType().getName()); } /** * @see org.eclipse.jface.action.Action#isEnabled() */ public boolean isEnabled() { Layer layer = getLayer(); if (layer == null) return false; return SLD.getSupportedTypes(layer).contains(getContentType()); } } /** * Action for firing up a specific editor. */ class SLDEditorAction extends Action { SLDEditorMenuAction parent; SLDEditorPart editor; public SLDEditorAction(SLDEditorPart editor, SLDEditorMenuAction parent) { super(); this.editor = editor; this.parent = parent; setImageDescriptor(getImageDescriptor(editor)); setText(editor.getLabel()); } public void run() { // update the icon to reflect the currently selected editor // parent.setImageDescriptor(getImageDescriptor()); if (editor instanceof SLDDisableEditorPart) { // disable the symbolizer @SuppressWarnings("unchecked") Class<Symbolizer> symbolizer = editor.getContentType(); sldContentManager.removeSymbolizer(symbolizer); } else { initEditor(editor); } // signal editor to reset editor.reset(); // finally show the editor page editorBook.setData(editor); // set the data of the editor book to be the active editor Composite page = editor.getPage(); editorBook.setVisible(true); editorBook.showPage(page); // page.setVisible( true ); } protected ImageDescriptor getImageDescriptor(SLDEditorPart editor1) { return editor1.getImageDescriptor(); } } /** * A editor that does nothing except displays a "disabled" icon and creates a blank page. */ class SLDDisableEditorPart extends SLDEditorPart { private Class<Symbolizer> contentType; public SLDDisableEditorPart(Class<Symbolizer> contentType) { this.contentType = contentType; setImageDescriptor(SLD.createDisabledImageDescriptor(contentType)); setLabel(Messages.SLDConfigurator_disable); } public void init() { // do nothing } /* * (non-Javadoc) * * @see org.locationtech.udig.style.sld.SLDEditorPart#getContentType() */ public Class getContentType() { return contentType; } /* * (non-Javadoc) * * @see org.locationtech.udig.style.sld.SLDEditorPart#createPartControl(org.eclipse.swt.widgets.Composite) */ protected Control createPartControl(Composite parent) { return new Composite(parent, SWT.NONE); } /* * (non-Javadoc) * * @see org.locationtech.udig.style.sld.SLDEditorPart#reset() */ public void reset() { // disable the content configurator sldContentManager.removeSymbolizer(contentType); } } }