/*************************************************** * * cismet GmbH, Saarbruecken, Germany * * ... and it just works. * ****************************************************/ /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package de.cismet.cismap.commons.featureservice; import edu.umd.cs.piccolo.PNode; import org.apache.log4j.Logger; import org.deegree.commons.utils.Pair; import org.deegree.rendering.r2d.legends.Legends; import org.deegree.style.persistence.sld.SLDParser; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.Namespace; import org.openide.util.Exceptions; import java.awt.Color; import java.awt.EventQueue; import java.awt.Graphics2D; import java.awt.event.ActionEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.IOException; import java.io.Reader; import java.io.StringReader; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.TreeMap; import javax.swing.Icon; import javax.swing.SwingWorker; import javax.xml.stream.XMLInputFactory; import de.cismet.cismap.commons.BoundingBox; import de.cismet.cismap.commons.ConvertableToXML; import de.cismet.cismap.commons.RetrievalServiceLayer; import de.cismet.cismap.commons.ServiceLayer; import de.cismet.cismap.commons.XBoundingBox; import de.cismet.cismap.commons.XMLObjectFactory; import de.cismet.cismap.commons.exceptions.ShapeFileImportAborted; import de.cismet.cismap.commons.features.DefaultFeatureServiceFeature; import de.cismet.cismap.commons.features.FeatureServiceFeature; import de.cismet.cismap.commons.featureservice.factory.AbstractFeatureFactory; import de.cismet.cismap.commons.featureservice.factory.CachingFeatureFactory; import de.cismet.cismap.commons.featureservice.factory.FeatureFactory; import de.cismet.cismap.commons.featureservice.style.Style; import de.cismet.cismap.commons.interaction.CismapBroker; import de.cismet.cismap.commons.interaction.DefaultQueryButtonAction; import de.cismet.cismap.commons.rasterservice.FeatureMapService; import de.cismet.cismap.commons.rasterservice.MapService; import de.cismet.cismap.commons.retrieval.AbstractRetrievalService; import de.cismet.cismap.commons.retrieval.RetrievalEvent; import de.cismet.tools.StaticXMLTools; /** * DOCUMENT ME! * * @author Pascal Dihé * @version $Revision$, $Date$ */ public abstract class AbstractFeatureService<FT extends FeatureServiceFeature, QT> extends AbstractRetrievalService implements MapService, ServiceLayer, RetrievalServiceLayer, FeatureMapService, ConvertableToXML, Cloneable, SLDStyledLayer { //~ Static fields/initializers --------------------------------------------- private static final transient Logger LOG = Logger.getLogger(AbstractFeatureService.class); public static String UNKNOWN = "UNKNOWN"; /* defaulttype-constant */ public static final String DEFAULT_TYPE = "default"; // NOI18N public static final List<DefaultQueryButtonAction> SQL_QUERY_BUTTONS = new ArrayList<DefaultQueryButtonAction>(); static { SQL_QUERY_BUTTONS.add(new DefaultQueryButtonAction("=")); SQL_QUERY_BUTTONS.add(new DefaultQueryButtonAction("<>")); SQL_QUERY_BUTTONS.add(new DefaultQueryButtonAction("Like")); SQL_QUERY_BUTTONS.add(new DefaultQueryButtonAction(">")); SQL_QUERY_BUTTONS.add(new DefaultQueryButtonAction(">=")); SQL_QUERY_BUTTONS.add(new DefaultQueryButtonAction("And")); SQL_QUERY_BUTTONS.add(new DefaultQueryButtonAction("<")); SQL_QUERY_BUTTONS.add(new DefaultQueryButtonAction("<=")); SQL_QUERY_BUTTONS.add(new DefaultQueryButtonAction("Or")); SQL_QUERY_BUTTONS.add(new DefaultQueryButtonAction("_", 1)); SQL_QUERY_BUTTONS.add(new DefaultQueryButtonAction("%", 1)); SQL_QUERY_BUTTONS.add(new DefaultQueryButtonAction("()") { { posCorrection = -1; } @Override public void actionPerformed(final ActionEvent e) { if (queryTextArea.getSelectionEnd() == 0) { super.actionPerformed(e); } else { final int start = queryTextArea.getSelectionStart(); final int end = queryTextArea.getSelectionEnd(); queryTextArea.insert("(", start); queryTextArea.insert(")", end + 1); // jTextArea1.setCaretPosition(end + 2); if (start == end) { CorrectCarret(posCorrection); } else { CorrectCarret((short)2); } } } }); SQL_QUERY_BUTTONS.add(new DefaultQueryButtonAction("Not")); SQL_QUERY_BUTTONS.add(new DefaultQueryButtonAction("Is")); } //~ Instance fields -------------------------------------------------------- /* determines either the layer is enabled or not */ // NOI18N /* determines either the layer is enabled or not */ protected boolean enabled = true; /* the bounding box which indicates the features of interest */ protected BoundingBox bb = null; /* the position of this layer in the layer hierachy */ protected int layerPosition; /* the name of this layer */ protected String name; /* determines the transparency of this layer */ protected float translucency = 0.2f; /* the encoding of the xml documents */ protected String encoding; /* maximal allowed amount of features, default is 1000 */ protected int maxFeatureCount = 1000; /* the list that holds all the featureServiceAttributes of the FeatureService */ protected Map<String, FeatureServiceAttribute> featureServiceAttributes; /* the Pnode that holds all the features */ protected PNode pNode; /* the visibility of this layer */ protected boolean visible = true; /* SwingWorker that retrieves the features in the desired area */ protected FeatureRetrievalWorker featureRetrievalWorker; /* is the featurelayer already initialized or not */ protected Boolean initialized = false; /* worker that retrieves to define the correct geometry */ protected LayerInitWorker layerInitWorker = null; protected LayerProperties layerProperties = null; protected FeatureFactory featureFactory = null; /* the list that holds the names of the featureServiceAttributes of the FeatureService in the specified order */ protected List<String> orderedFeatureServiceAttributes; protected List<DefaultQueryButtonAction> queryButtons = new ArrayList<DefaultQueryButtonAction>(SQL_QUERY_BUTTONS); protected boolean initializedFromElement = false; String sldDefinition; final XMLInputFactory factory = XMLInputFactory.newInstance(); Legends legends = new Legends(); private boolean initialisationError = false; private Element initElement = null; private boolean selectable = true; //~ Constructors ----------------------------------------------------------- /** * Creates a new <b>uninitilaised</b> instance of a feature service with layer properties set. The Service is fully * initialised upon the first call to the {@code retrieve()} operation. */ public AbstractFeatureService() { // TODO: mayor design flaw as the usage of an abstract method during construction time can lead to indeterminate // state this.setLayerProperties(this.createLayerProperties()); } /** * Creates a new AbstractFeatureService from a XML-element. Sets all properties of the XML Element but does <b> * not</b> initialise. Since the initialisation may take some time, it is perfomed upon the first call to the * {@code retrieve()} operation which is rum from separate thread. * * @param e XML-element with FeatureService-configuration * * @throws Exception java.lang.Exception if something went wrong * @throws ClassNotFoundException DOCUMENT ME! * * @see isInitialised() */ public AbstractFeatureService(final Element e) throws Exception { // this(); LOG.info("creating new FeatureService instance from xml element '" + e.getName() + "'"); // NOI18N if (e.getName().equals(this.getFeatureLayerType())) { this.initFromElement(e); } else if (e.getChild(this.getFeatureLayerType()) != null) { this.initFromElement(e.getChild(this.getFeatureLayerType())); } else { LOG.error("FeatureService could not be initailised from xml: unsupported element '" + e.getName() + "'"); // NOI18N throw new ClassNotFoundException("FeatureService could not be initailised from xml: unsupported element '" + e.getName() + "'"); // NOI18N } if (this.getLayerProperties() == null) { LOG.warn( "LayerProperties not properly initialised from XML Element, creating new Properties upon next retrieval"); // NOI18N this.layerProperties = this.createLayerProperties(); } if ((this.getFeatureServiceAttributes() == null) || (this.getFeatureServiceAttributes().size() == 0)) { LOG.warn( "FeatureServiceAttributes not properly initialised from XML Element, creating new Attributes upon next retrieval"); // NOI18N } } /** * Create a new <b>uninitialised</b> AbstractFeatureService except for the name and featureServiceAttributes. * * @param name the name of this FeatureService * @param attributes featureServiceAttributes vector with all FeatureServiceAttributes of the FeatureService */ public AbstractFeatureService(final String name, final List<FeatureServiceAttribute> attributes) { // this(); this.setName(name); this.setFeatureServiceAttributes(attributes); } /** * Protected Constructor that clones (shallow) the delivered AbstractFeatureService. Attributes, layer properties * and feature factories are not cloned deeply. The FeatureService to be cloned should be initilaised. * * @param afs FeatureService that should be cloned */ protected AbstractFeatureService(final AbstractFeatureService afs) { // this(); // initilaisation updates also the cloned object! if (!afs.isInitialized()) { LOG.warn("creating copy of uninitialised feature service"); // NOI18N } this.setLayerPosition(afs.getLayerPosition()); this.setName(afs.getName()); this.setEncoding(afs.getEncoding()); // The cloned featureService and the origin featureService should not use the same pnode, // because this would lead to problems, if the cloned layer and the origin layer are // used in 2 different MappingComponents // this.setPNode(afs.getPNode()); this.setTranslucency(afs.getTranslucency()); this.setEncoding(afs.getEncoding()); this.setEnabled(afs.isEnabled()); this.layerProperties = (afs.getLayerProperties() != null) ? afs.getLayerProperties().clone() : null; this.featureFactory = (afs.getFeatureFactory() != null) ? afs.getFeatureFactory().clone() : null; final TreeMap<String, FeatureServiceAttribute> attriuteMap = new TreeMap(); attriuteMap.putAll(afs.getFeatureServiceAttributes()); this.setFeatureServiceAttributes(attriuteMap); this.setInitialized(afs.isInitialized()); this.setInitialisationError(afs.getInitialisationError()); this.setInitElement(afs.getInitElement()); this.setSelectable(afs.isSelectable()); this.sldDefinition = afs.sldDefinition; } //~ Methods ---------------------------------------------------------------- /** * Initialises the FeatureService instance. If the service has already been initialised, the operation clears the * layerProperties, the featureFactory and the featureServiceAttributes and forces a complete re-initialisation. * * @throws Exception java.lang.Exception if somethin went wrong */ protected void init() throws Exception { // *should* never happen .... if ((layerInitWorker == null) || layerInitWorker.isDone()) { LOG.error("strange synchronisation problem in Layer Initialisation Thread"); // NOI18N throw new Exception("strange synchronisation problem in Layer Initialisation Thread"); // NOI18N } // check if canceled ....................................................... if (layerInitWorker.isCancelled()) { LOG.warn("LIW[" + layerInitWorker.getId() + "]: init is canceled"); // NOI18N return; } // .......................................................................... if (this.isInitialized() || this.isRefreshNeeded()) { LOG.warn("layer already initialised, forcing complete re-initialisation"); // NOI18N this.setInitialized(false); featureFactory = null; featureServiceAttributes = null; // this.layerProperties = null; // this.featureFactory = null; // this.featureServiceAttributes = null; } if (this.getLayerProperties() == null) { if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("init(): LayerProperties not yet set, creating new LayerProperties instance"); // NOI18N } } this.layerProperties = this.createLayerProperties(); } else { if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("init(): Layer Properties already created"); // NOI18N } } } // check if canceled ....................................................... if (layerInitWorker.isCancelled()) { LOG.warn("LIW[" + layerInitWorker.getId() + "]: init is canceled"); // NOI18N return; } // .......................................................................... if (this.featureFactory == null) { if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("init(): Feature Factory not yet set, creating new Feature Factory instance"); // NOI18N } } // create the feature Factory // all variables required by the concrete FeatureFactory constructor must // have been initialised! this.featureFactory = this.createFeatureFactory(); } else { if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("init(): Feature Factory already created"); // NOI18N } } } // set common properties of the factory // implemntation specific properties must be set in the createFeatureFactory() this.featureFactory.setMaxFeatureCount(this.getMaxFeatureCount()); this.featureFactory.setLayerProperties(layerProperties); // check if canceled ....................................................... if (layerInitWorker.isCancelled()) { LOG.warn("LIW[" + layerInitWorker.getId() + "]: init is canceled"); // NOI18N return; } // .......................................................................... if ((this.getFeatureServiceAttributes() == null) || (this.getFeatureServiceAttributes().size() == 0)) { if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug( "init(): Feature Service Attributes not yet set, creating new Feature Service Attribute"); // NOI18N } } try { this.setFeatureServiceAttributes(featureFactory.createAttributes(layerInitWorker)); } catch (UnsupportedOperationException uoe) { if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("Feature Factory '" + this.getFeatureFactory().getClass().getSimpleName() + "' does not support Attributes"); // NOI18N } } if (this.getFeatureServiceAttributes() == null) { this.setFeatureServiceAttributes(new ArrayList()); } } } else { if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("init(): Feature Service Attributes already created"); // NOI18N } } } // check if canceled ....................................................... if (layerInitWorker.isCancelled()) { LOG.warn("LIW[" + layerInitWorker.getId() + "]: init is canceled"); // NOI18N return; } // .......................................................................... // idExpression plausibility check if ((this.getLayerProperties().getIdExpressionType() == LayerProperties.EXPRESSIONTYPE_PROPERTYNAME) && (this.getLayerProperties().getIdExpression() != null) && (this.getFeatureServiceAttributes() != null) && (this.getFeatureServiceAttributes().size() > 0)) { if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("checking if property id expression '" + this.getLayerProperties().getIdExpression() + "' is valid"); // NOI18N } } boolean found = false; for (final FeatureServiceAttribute attribute : this.getFeatureServiceAttributes().values()) { if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("checking attribute '" + attribute.getName() + "'"); // NOI18N } } found = attribute.getName().equals(this.getLayerProperties().getIdExpression()); if (found) { if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("attribute is valid: " + attribute.getName()); // NOI18N } } break; } } if (!found) { LOG.warn("property id expression '" + this.getLayerProperties().getIdExpression() + "' not found in attributes, resetting to undefined"); // NOI18N this.getLayerProperties().setIdExpression(null, LayerProperties.EXPRESSIONTYPE_UNDEFINED); } } // check if canceled ....................................................... if (layerInitWorker.isCancelled()) { LOG.warn("LIW[" + layerInitWorker.getId() + "]: init is canceled"); // NOI18N return; } // .......................................................................... if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("init(): performing additional implementation specific initialisation"); // NOI18N } } this.initConcreteInstance(); // initilaized = true is set in the layerInitWorker } /** * Initialises the feature service and blocks until the initialisation of the service is completed. If the * initialisation of the service is already in progress, this method wait until the initialisation is complete, if * this thread is not running in edt. * * @throws Exception DOCUMENT ME! */ public void initAndWait() throws Exception { if (!initialized && ((layerInitWorker == null) || layerInitWorker.isCancelled())) { layerInitWorker = new LayerInitWorker(); init(); layerInitWorker = null; } else if (!initialized) { if (!EventQueue.isDispatchThread()) { while ((layerInitWorker != null) && !layerInitWorker.isDone()) { try { Thread.sleep(50); } catch (InterruptedException e) { // nothing to do } } } } } /** * Creates an instance of a service specific LayerProperties implementation. * * @return layer properties to be used */ protected abstract LayerProperties createLayerProperties(); /** * Creates an instance of a service specific FeatureFactory implementation. All variables required by the concrete * FeatureFactory, e.g. the Layer Properties must have been initialised before this operation is invoked. * * @return the constructed FeatureFactory * * @throws Exception id the costruction failed */ protected abstract FeatureFactory createFeatureFactory() throws Exception; /** * Get the value of featureFactory. * * @return the value of featureFactory */ public FeatureFactory getFeatureFactory() { return featureFactory; } /** * Get the value of query. * * @return the value of query */ public abstract QT getQuery(); /** * Set the value of query. * * @param query new value of query */ public abstract void setQuery(QT query); /** * Cancels the retrievel or the initialisation threads. * * @param workerThread DOCUMENT ME! * * @return {@code true} if a running thread was found and canceled */ protected boolean cancel(final SwingWorker workerThread) { boolean canceled = false; if ((workerThread != null) && (!workerThread.isDone() || !workerThread.isCancelled())) { if (workerThread != null) { LOG.warn("canceling Worker Thread: " + workerThread); // NOI18N final boolean cancel = workerThread.cancel(true); if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("Worker Thread: " + workerThread + " canceled: " + cancel + " (" + workerThread.isCancelled() + ")"); // NOI18N } } } canceled = true; } return canceled; } /** * Creates a new LayerInitWorker or FeatureRetrievalWorker and launches the initialisation or retrieval-process * depending wheter the layer has already been initialised or the forced parameter is set to true. A * re-initialisation clears the attribute and layer properties cache and thus resets any saved properties to default * values. * * @param forced forces a re-initialisation of the layer */ @Override public synchronized void retrieve(final boolean forced) { if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("retrieve started (forced = " + forced + ")"); // NOI18N } } if ((featureRetrievalWorker != null) && !featureRetrievalWorker.isDone()) { if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("old retrieval thread still running, trying to cancel '" + featureRetrievalWorker.getId() + "' (already canceled = " + featureRetrievalWorker.isCancelled() + ")"); // NOI18N } } final FeatureRetrievalWorker currentWorker = featureRetrievalWorker; // new Thread(new Runnable() { // // @Override // public void run() { synchronized (featureFactory) { if (featureFactory instanceof AbstractFeatureFactory) { ((AbstractFeatureFactory)featureFactory).waitUntilInterruptedIsAllowed(); } cancel(currentWorker); } // } // }).start(); } if (!this.isEnabled() && !this.isVisible()) { LOG.warn("Service '" + this.getName() + "' is disabled and invisible, ignoring retrieve() request"); // NOI18N return; } // Initialisierung bereits vorgenommen, d.h. es gibt z.B. Feature Service Attribute if (this.isInitialized() && !this.isRefreshNeeded() /*&& !forced*/) { if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("Layer already initialized, starting feature retrieval"); // NOI18N } } if (forced && (getFeatureFactory() instanceof CachingFeatureFactory)) { if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("retrieval forced, flushing cache"); // NOI18N } } if ((featureRetrievalWorker != null) && !featureRetrievalWorker.isDone()) { LOG.warn("must wait until thread '" + featureRetrievalWorker + "' is finished before flushing cache"); // NOI18N while (!featureRetrievalWorker.isDone()) { } if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("thread '" + featureRetrievalWorker + "'is finished, flushing cache"); // NOI18N } } } ((CachingFeatureFactory)getFeatureFactory()).flush(); } this.featureRetrievalWorker = new FeatureRetrievalWorker(); featureRetrievalWorker.execute(); } else { if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("Layer not yet initialized (" + this.initialized + ") or refresh needed (" + this.isRefreshNeeded() + "), starting LayerInitWorker"); // NOI18N } } if (layerInitWorker == null) { layerInitWorker = new LayerInitWorker(); layerInitWorker.execute(); } else { LOG.warn("Layer wird z.Z. initialisiert --> request wird ignoriert"); // NOI18N } } } /** * This operation is invoked after the default initialisation. Implementation classes may implement this method to * perform addditional initialisations. * * @throws Exception if the initialisation fails */ protected abstract void initConcreteInstance() throws Exception; /** * DOCUMENT ME! * * @return DOCUMENT ME! */ protected abstract String getFeatureLayerType(); /** * DOCUMENT ME! * * @param type DOCUMENT ME! * * @return DOCUMENT ME! */ public abstract Icon getLayerIcon(int type); /** * Packs the properties of the AbstractFeatureService as JDom-element. * * @return JDom-element that outlines this AbstractFeatureService */ public boolean isInitialized() { return initialized; } /** * DOCUMENT ME! * * @param isInitialized DOCUMENT ME! */ protected void setInitialized(final boolean isInitialized) { this.initialized = isInitialized; } /** * Returns a list of all featureServiceAttributes of this featureservice. * * @return DOCUMENT ME! */ public Map<String, FeatureServiceAttribute> getFeatureServiceAttributes() { return this.featureServiceAttributes; } /** * Setter for the featureServiceAttributes of the featureservice. * * @param featureServiceAttributes featureServiceAttributes to set */ public void setFeatureServiceAttributes(final Map<String, FeatureServiceAttribute> featureServiceAttributes) { this.featureServiceAttributes = featureServiceAttributes; } /** * Returns a list of all featureServiceAttributes of this featureservice. * * @return DOCUMENT ME! */ public List<String> getOrderedFeatureServiceAttributes() { return this.orderedFeatureServiceAttributes; } /** * Setter for the featureServiceAttributes of the featureservice. * * @param orderedFeatureServiceAttributes featureServiceAttributes to set */ public void setOrderedFeatureServiceAttributes(final List<String> orderedFeatureServiceAttributes) { this.orderedFeatureServiceAttributes = orderedFeatureServiceAttributes; } /** * Setter for the featureServiceAttributes of the featureservice. * * @param featureServiceAttributesVector featureServiceAttributes to set */ protected void setFeatureServiceAttributes(final List<FeatureServiceAttribute> featureServiceAttributesVector) { if (featureServiceAttributesVector != null) { if (this.featureServiceAttributes == null) { this.featureServiceAttributes = new HashMap(featureServiceAttributesVector.size()); this.orderedFeatureServiceAttributes = new ArrayList<String>(); } else { this.featureServiceAttributes.clear(); this.orderedFeatureServiceAttributes.clear(); } for (final FeatureServiceAttribute fsa : featureServiceAttributesVector) { this.orderedFeatureServiceAttributes.add(fsa.getName()); this.featureServiceAttributes.put(fsa.getName(), fsa); } } } /** * This Method is used to set the bounding box to determine which features should be retrieved. * * @return DOCUMENT ME! */ public BoundingBox getBoundingBox() { return bb; } /** * DOCUMENT ME! * * @param bb DOCUMENT ME! */ @Override public void setBoundingBox(final BoundingBox bb) { this.bb = bb; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public String getEncoding() { return encoding; } /** * DOCUMENT ME! * * @param encoding DOCUMENT ME! */ public void setEncoding(final String encoding) { this.encoding = encoding; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public int getMaxFeatureCount() { return maxFeatureCount; } /** * DOCUMENT ME! * * @param maxFeatureCount DOCUMENT ME! */ public void setMaxFeatureCount(final int maxFeatureCount) { this.maxFeatureCount = maxFeatureCount; if (this.getFeatureFactory() != null) { this.getFeatureFactory().setMaxFeatureCount(maxFeatureCount); } } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public LayerProperties getLayerProperties() { return layerProperties; } /** * DOCUMENT ME! * * @param layerProperties DOCUMENT ME! */ public void setLayerProperties(final LayerProperties layerProperties) { setLayerProperties(layerProperties, true); } /** * Sets the new layer properties of the service and. * * @param layerProperties DOCUMENT ME! * @param refreshFeatures DOCUMENT ME! */ public void setLayerProperties(final LayerProperties layerProperties, final boolean refreshFeatures) { this.layerProperties = layerProperties; if (this.featureFactory != null) { if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("setLayerProperties: new layer properties are also applied to all cached features!"); // NOI18N } } // layer properties are appiled to last created features if ((featureRetrievalWorker != null) && !featureRetrievalWorker.isDone()) { LOG.warn("must wait until thread '" + featureRetrievalWorker + "' is finished before applying new layer properties"); // NOI18N while (!featureRetrievalWorker.isDone()) { // wait .... } if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("thread '" + featureRetrievalWorker + "' is finished, applying new layer properties"); // NOI18N } } } this.featureFactory.setLayerProperties(layerProperties); if (refreshFeatures) { refreshFeatures(); } } } /** * Sets the new layer properties of the service and. */ public void refresh() { if (this.featureFactory != null) { if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("setLayerProperties: new layer properties are also applied to all cached features!"); // NOI18N } } // layer properties are applied to last created features if ((featureRetrievalWorker != null) && !featureRetrievalWorker.isDone()) { LOG.warn("must wait until thread '" + featureRetrievalWorker + "' is finished before applying new layer properties"); // NOI18N while (!featureRetrievalWorker.isDone()) { // wait .... } if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("thread '" + featureRetrievalWorker + "' is finished, applying new layer properties"); // NOI18N } } } this.featureFactory.setLayerProperties(layerProperties); refreshFeatures(); } } /** * Deliveres the transparency value of the Featues. * * @return the translucency value */ @Override public float getTranslucency() { return translucency; } /** * Setter for the transparency value. * * @param t the new transparency value */ @Override public void setTranslucency(final float t) { this.translucency = t; } /** * Setter for the name of the AbstractFeatureService. * * @param name the new name that will be set */ @Override public void setName(final String name) { this.name = name; if (featureFactory != null) { featureFactory.setLayerName(name); } } /** * This method delivers the name of the layer. * * @return the name of the layer */ @Override public String getName() { return name; } /** * This method delivers the postion of the layer in the layer hierachy. * * @return the postion of the layer in the layer hierarchy */ @Override public int getLayerPosition() { return layerPosition; } /** * Sets the layer postion. Dependet on this value the layer will be positioned at top of other layers or behind * other layers * * @param layerPosition The integer value which determines the postion in the layer hierarchy */ @Override public void setLayerPosition(final int layerPosition) { this.layerPosition = layerPosition; } /** * Returns if the layer is enabled or disabled. * * @return either true if the layer is enabled or false if its not */ @Override public boolean isEnabled() { return enabled; } /** * Enables or disables the Layer. * * @param enabled true enables the layer, false disables it */ @Override public void setEnabled(final boolean enabled) { if (!enabled) { if (!this.canBeDisabled()) { LOG.warn("Service '" + this.getName() + "' cannot be disabled"); // NOI18N } else { this.enabled = false; // } } else { this.enabled = true; } } /** * This method checks either a layer can be disabled or not. * * @return true if the layer can be disabled or false if not */ @Override public boolean canBeDisabled() { return true; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ @Override public boolean isVisible() { return visible; } /** * DOCUMENT ME! * * @param visible DOCUMENT ME! */ public void setVisible(final boolean visible) { this.visible = visible; } /** * DOCUMENT ME! * * @param height DOCUMENT ME! * @param width DOCUMENT ME! */ @Override public void setSize(final int height, final int width) { } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ @Override public PNode getPNode() { return pNode; } /** * DOCUMENT ME! * * @param pNode DOCUMENT ME! */ @Override public void setPNode(final PNode pNode) { this.pNode = pNode; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ @Override public String toString() { return this.getName(); } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ @Override public Element toElement() { final Element element = new Element(getFeatureLayerType()); element.setAttribute("name", getName()); // NOI18N element.setAttribute("type", this.getClass().getCanonicalName()); // NOI18N element.setAttribute("visible", Boolean.valueOf(getPNode().getVisible()).toString()); // NOI18N element.setAttribute("enabled", Boolean.valueOf(isEnabled()).toString()); // NOI18N element.setAttribute("translucency", new Float(getTranslucency()).toString()); // NOI18N element.setAttribute("maxFeatureCount", new Integer(this.getMaxFeatureCount()).toString()); // NOI18N element.setAttribute("layerPosition", new Integer(this.getLayerPosition()).toString()); // NOI18N element.setAttribute("isSelectable", Boolean.toString(this.isSelectable())); // NOI18N if ((this.getFeatureServiceAttributes() != null) && (this.getFeatureServiceAttributes().size() > 0)) { final Element attrib = new Element("Attributes"); // NOI18N for (final String key : getOrderedFeatureServiceAttributes()) { final FeatureServiceAttribute e = getFeatureServiceAttributes().get(key); attrib.addContent(e.toElement()); } element.addContent(attrib); } else { LOG.warn("FeatureServiceAttributes are null and will not be saved"); // NOI18N } if (this.getLayerProperties() != null) { final Element layerPropertiesElement = this.getLayerProperties().toElement(); element.addContent(layerPropertiesElement); } else { LOG.warn("Layer Properties are null and will not be saved"); // NOI18N } try { if (getSLDDefiniton() != null) { final Document sldDoc = new org.jdom.input.SAXBuilder().build(getSLDDefiniton()); element.addContent(sldDoc.detachRootElement()); } } catch (JDOMException ex) { Exceptions.printStackTrace(ex); } catch (IOException ex) { Exceptions.printStackTrace(ex); } return element; } /** * DOCUMENT ME! * * @param element DOCUMENT ME! * * @throws Exception DOCUMENT ME! */ @Override public void initFromElement(Element element) throws Exception { if (element == null) { element = this.getInitElement(); } else { this.setInitElement((Element)element.clone()); } if (element.getAttributeValue("name") != null) // NOI18N { this.setName(element.getAttributeValue("name")); // NOI18N } if (element.getAttributeValue("visible") != null) // NOI18N { this.setVisible(Boolean.valueOf(element.getAttributeValue("visible"))); // NOI18N } if (element.getAttributeValue("translucency") != null) // NOI18N { this.setTranslucency(element.getAttribute("translucency").getFloatValue()); // NOI18N } if (element.getAttributeValue("enabled") != null) // NOI18N { final Float minOpacity = CismapBroker.getInstance().getMinOpacityToStayEnabled(); if ((minOpacity != null) && ((getTranslucency() <= minOpacity) || !isVisible())) { this.setEnabled(false); // NOI18N } else { this.setEnabled(Boolean.valueOf(element.getAttributeValue("enabled"))); // NOI18N } } if (element.getAttributeValue("maxFeatureCount") != null) // NOI18N { this.setMaxFeatureCount(element.getAttribute("maxFeatureCount").getIntValue()); // NOI18N } if (element.getAttributeValue("layerPosition") != null) // NOI18N { this.setLayerPosition(element.getAttribute("layerPosition").getIntValue()); // NOI18N } if (element.getAttributeValue("isSelectable") != null) // NOI18N { this.setSelectable(element.getAttribute("isSelectable").getBooleanValue()); // NOI18N } final Element xmlAttributes = element.getChild("Attributes"); // NOI18N if (xmlAttributes != null) { featureServiceAttributes = FeatureServiceUtilities.getFeatureServiceAttributes(xmlAttributes); orderedFeatureServiceAttributes = FeatureServiceUtilities.getOrderedFeatureServiceAttributes(xmlAttributes); this.setFeatureServiceAttributes(featureServiceAttributes); } if (element.getAttribute(ConvertableToXML.TYPE_ATTRIBUTE) == null) { LOG.warn("fromElement: restoring object from deprecated xml element"); // NOI18N try { this.fromOldElement(element); } catch (final Exception e) { LOG.warn("could not restore deprecated configuration: \n" + e.getMessage(), e); // NOI18N } } else if (element.getChild("LayerProperties") != null) // NOI18N { LayerProperties restoredLayerProperties = null; try { final Element layerPropertiesElement = element.getChild(LayerProperties.LAYER_PROPERTIES_ELEMENT); restoredLayerProperties = (LayerProperties)XMLObjectFactory.restoreObjectfromElement( layerPropertiesElement); restoredLayerProperties.setFeatureService(this); } catch (Exception t) { LOG.error("could not restore generic style element '" // NOI18N + element.getChild("LayerProperties").getAttribute(ConvertableToXML.TYPE_ATTRIBUTE) + "': \n" + t.getMessage(), t); // NOI18N } this.layerProperties = restoredLayerProperties; } else { LOG.warn("no layer properties "); // NOI18N } final Element sldStyle = element.getChild( "StyledLayerDescriptor", Namespace.getNamespace("http://www.opengis.net/sld")); if (sldStyle != null) { sldDefinition = new org.jdom.output.XMLOutputter().outputString(sldStyle); } initializedFromElement = true; } /** * DOCUMENT ME! * * @param element old XML Configuration * * @deprecated DOCUMENT ME! */ @Deprecated private void fromOldElement(final Element element) { final DefaultFeatureServiceFeature wfsFeature = new DefaultFeatureServiceFeature(); final Element renderingFeature = element.getChild("renderingFeature").getChild("DefaultWFSFeature"); // NOI18N wfsFeature.setIdExpression(renderingFeature.getAttributeValue("idExpression")); // NOI18N final int lineWidth = Integer.parseInt(renderingFeature.getAttributeValue("lineWidth")); // NOI18N wfsFeature.setLineWidth(lineWidth); wfsFeature.setTransparency(Float.parseFloat(renderingFeature.getAttributeValue("transparency"))); // NOI18N wfsFeature.setPrimaryAnnotation(renderingFeature.getAttributeValue("primaryAnnotation")); // NOI18N wfsFeature.setSecondaryAnnotation(renderingFeature.getAttributeValue("secondaryAnnotation")); // NOI18N wfsFeature.setPrimaryAnnotationScaling(Double.parseDouble( renderingFeature.getAttributeValue("primaryAnnotationScaling"))); // NOI18N wfsFeature.setPrimaryAnnotationJustification(Float.parseFloat( renderingFeature.getAttributeValue("primaryAnnotationJustification"))); // NOI18N wfsFeature.setMaxScaleDenominator(Integer.parseInt(renderingFeature.getAttributeValue("maxScaleDenominator"))); // NOI18N wfsFeature.setMinScaleDenominator(Integer.parseInt(renderingFeature.getAttributeValue("minScaleDenominator"))); // NOI18N wfsFeature.setAutoScale(Boolean.parseBoolean(renderingFeature.getAttributeValue("autoscale"))); // NOI18N // color kann null sein (fill disabled oder line disabled) Color fill = null; Color line = null; if (renderingFeature.getChild("fillingColor") != null) // NOI18N { fill = StaticXMLTools.convertXMLElementToColor(renderingFeature.getChild("fillingColor").getChild("Color")); // NOI18N } wfsFeature.setFillingPaint(fill); if (renderingFeature.getChild("lineColor") != null) // NOI18N { line = StaticXMLTools.convertXMLElementToColor(renderingFeature.getChild("lineColor").getChild("Color")); // NOI18N } wfsFeature.setLinePaint(line); wfsFeature.setPrimaryAnnotationFont(StaticXMLTools.convertXMLElementToFont( renderingFeature.getChild("primaryAnnotationFont").getChild("Font"))); // NOI18N wfsFeature.setPrimaryAnnotationPaint(StaticXMLTools.convertXMLElementToColor( renderingFeature.getChild("primaryAnnotationColor").getChild("Color"))); // NOI18N wfsFeature.setHighlightingEnabled(Boolean.parseBoolean( renderingFeature.getAttributeValue("highlightingEnabled"))); // NOI18N wfsFeature.getLayerProperties().getStyle().setPointSymbolFilename(Style.AUTO_POINTSYMBOL); this.layerProperties = wfsFeature.getLayerProperties(); } /** * DOCUMENT ME! * * @param initialisationError DOCUMENT ME! */ public void setInitialisationError(final boolean initialisationError) { this.initialisationError = initialisationError; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public boolean getInitialisationError() { return this.initialisationError; } /** * The query buttons, which should be used by the query search. * * @return DOCUMENT ME! */ public List<DefaultQueryButtonAction> getQueryButtons() { return queryButtons; } /** * DOCUMENT ME! * * @param name DOCUMENT ME! * * @return DOCUMENT ME! */ public String decoratePropertyName(final String name) { return name; } /** * Determines, if the attribute decoration should be hidden from the user. See <code>decoratePropertyName(String * name)</code> * * @return True, iff the attribute decoration of the search query should be hidden from the user */ public boolean decorateLater() { return false; } /** * Decorates the given query. So that it con be used with the services. This method is typically used, if <code> * decorateLater()</code> returns true. This method adds all attribute decorations, which should be hidden from the * user. * * @param query the query to decorate * * @return the decorated query */ public String decorateQuery(final String query) { return query; } /** * DOCUMENT ME! * * @param columnName DOCUMENT ME! * @param value DOCUMENT ME! * * @return DOCUMENT ME! */ public String decoratePropertyValue(final String columnName, final String value) { return "'" + value + "'"; } /** * DOCUMENT ME! * * @param boundingBox DOCUMENT ME! * @param offset DOCUMENT ME! * @param limit DOCUMENT ME! * @param orderBy DOCUMENT ME! * * @return DOCUMENT ME! * * @throws Exception DOCUMENT ME! */ public List retrieveFeatures(final BoundingBox boundingBox, final int offset, final int limit, final String orderBy) throws Exception { if (!initialized) { initAndWait(); } return getFeatureFactory().createFeatures(getQuery(), boundingBox, layerInitWorker); } /** * DOCUMENT ME! * * @param query DOCUMENT ME! * @param boundingBox DOCUMENT ME! * * @return DOCUMENT ME! */ public int getFeatureCount(final QT query, final BoundingBox boundingBox) { if (!initialized) { try { initAndWait(); } catch (Exception e) { LOG.error("Error while initialising feature service.", e); } } if (boundingBox == null) { return getFeatureFactory().getFeatureCount(query, this.bb); } else { return getFeatureFactory().getFeatureCount(query, boundingBox); } } /** * DOCUMENT ME! * * @param boundingBox DOCUMENT ME! * * @return DOCUMENT ME! */ public int getFeatureCount(final BoundingBox boundingBox) { return getFeatureCount(getQuery(), boundingBox); } /** * This operation class the {@code createFeatures()} operation of the current FeatureFactory. Implementation classes * may override this method to pass additional parameters to the {@code createFeatures()} operation of the specific * FeatureFactory implementation. * * @param worker the current worker thred that is observed * * @return the FeatureServiceFeatures created by the current Factory * * @throws Exception DOCUMENT ME! */ protected List<FT> retrieveFeatures(final FeatureRetrievalWorker worker) throws Exception { if (initialisationError || ((this instanceof WebFeatureService) && (((WebFeatureService)this).getFeature() == null))) { if (((this instanceof WebFeatureService) && (((WebFeatureService)this).getFeature() == null))) { initialisationError = true; } initFromElement(null); setInitialized(false); featureFactory = createFeatureFactory(); this.featureFactory.setMaxFeatureCount(this.getMaxFeatureCount()); this.featureFactory.setLayerProperties(layerProperties); initConcreteInstance(); if (initialisationError) { throw new Exception(getErrorObject().toString()); } } if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("FRW[" + worker.getId() + "]: retrieveFeatures started"); // NOI18N } } // check if canceled ....................................................... if (worker.isCancelled()) { LOG.warn("FRW[" + worker.getId() + "]: retrieveFeatures is canceled"); // NOI18N return null; } // check if canceled ....................................................... final long start = System.currentTimeMillis(); final List<FT> features = getFeatureFactory().createFeatures(this.getQuery(), this.getBoundingBox(), worker); if (features != null) { LOG.info("FRW[" + worker.getId() + "]: " + features.size() + " features retrieved in " + (System.currentTimeMillis() - start) + " ms"); // NOI18N } else { LOG.warn("FRW[" + worker.getId() + "]: no features found (canceled=" + worker.isCancelled() + ")"); // NOI18N } if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("FRW[" + worker.getId() + "]: retrieveFeatures completed"); // NOI18N } } return features; } /** * DOCUMENT ME! * * @return the initElement */ public Element getInitElement() { return initElement; } /** * DOCUMENT ME! * * @param initElement the initElement to set */ public void setInitElement(final Element initElement) { this.initElement = initElement; } /** * DOCUMENT ME! * * @param selectable DOCUMENT ME! */ public void setSelectable(final boolean selectable) { this.selectable = selectable; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public boolean isSelectable() { return this.selectable; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public boolean isEditable() { return false; } @Override public Reader getSLDDefiniton() { return (sldDefinition == null) ? null // new InputStreamReader(getClass().getResourceAsStream("/testSLD.xml")) : new StringReader(sldDefinition); } @Override public void setSLDInputStream(final String inputStream) { if ((inputStream == null) || inputStream.isEmpty()) { sldDefinition = null; featureFactory.setSLDStyle(null); return; } sldDefinition = inputStream; final Map<String, LinkedList<org.deegree.style.se.unevaluated.Style>> styles = parseSLD(new StringReader( inputStream)); if ((styles == null) || styles.isEmpty()) { return; } featureFactory.setSLDStyle(styles); } /** * DOCUMENT ME! * * @param input DOCUMENT ME! * * @return DOCUMENT ME! */ protected Map<String, LinkedList<org.deegree.style.se.unevaluated.Style>> parseSLD(final Reader input) { Map<String, LinkedList<org.deegree.style.se.unevaluated.Style>> styles = null; try { if (input != null) { styles = SLDParser.getStyles(factory.createXMLStreamReader(input)); } } catch (Exception ex) { LOG.error("Fehler in der SLD", ex); } if (styles == null) { LOG.info("SLD Parser funtkioniert nicht"); } return styles; } @Override public Pair<Integer, Integer> getLegendSize(final int nr) { if (featureFactory instanceof AbstractFeatureFactory) { final AbstractFeatureFactory aff = ((AbstractFeatureFactory)featureFactory); return getLegendSize((org.deegree.style.se.unevaluated.Style)aff.getStyle(aff.layerName).get(0)); } return null; } /** * DOCUMENT ME! * * @param style DOCUMENT ME! * * @return DOCUMENT ME! */ private Pair<Integer, Integer> getLegendSize(final org.deegree.style.se.unevaluated.Style style) { return legends.getLegendSize(style); } @Override public Pair<Integer, Integer> getLegendSize() { return getLegendSize(0); } @Override public List<Pair<Integer, Integer>> getLegendSizes() { final AbstractFeatureFactory aff = ((AbstractFeatureFactory)featureFactory); final List<org.deegree.style.se.unevaluated.Style> styles = aff.getStyle(aff.layerName); final List<Pair<Integer, Integer>> sizes = new LinkedList<Pair<Integer, Integer>>(); for (final org.deegree.style.se.unevaluated.Style style : styles) { sizes.add(getLegendSize(style)); } return sizes; } @Override public void getLegend(final int width, final int height, final Graphics2D g2d) { getLegend(0, width, height, g2d); } @Override public void getLegend(final int nr, final int width, final int height, final Graphics2D g2d) { if (featureFactory instanceof AbstractFeatureFactory) { final AbstractFeatureFactory aff = ((AbstractFeatureFactory)featureFactory); getLegend((org.deegree.style.se.unevaluated.Style)aff.getStyle(aff.layerName).get(0), width, height, g2d); } } /** * DOCUMENT ME! * * @param style DOCUMENT ME! * @param width DOCUMENT ME! * @param height DOCUMENT ME! * @param g2d DOCUMENT ME! */ private void getLegend(final org.deegree.style.se.unevaluated.Style style, final int width, final int height, final Graphics2D g2d) { legends.paintLegend(style, width, height, g2d); } @Override public void getLegends(final List<Pair<Integer, Integer>> sizes, final Graphics2D[] g2d) { final AbstractFeatureFactory aff = ((AbstractFeatureFactory)featureFactory); final List<org.deegree.style.se.unevaluated.Style> styles = aff.getStyle(aff.layerName); for (int i = 0; i < styles.size(); i++) { legends.paintLegend(styles.get(i), sizes.get(i).first, sizes.get(i).second, g2d[i]); } } /** * DOCUMENT ME! */ public void refreshFeatures() { final List<FT> lastCreatedFeatures = this.featureFactory.getLastCreatedFeatures(); if (lastCreatedFeatures.size() > 0) { if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug(lastCreatedFeatures.size() + " last created features refreshed, fiering retrival event"); // NOI18N } } EventQueue.invokeLater(new Runnable() { @Override public void run() { final RetrievalEvent re = new RetrievalEvent(); re.setIsComplete(true); re.setHasErrors(false); re.setRefreshExisting(true); re.setRetrievedObject(lastCreatedFeatures); re.setRequestIdentifier(System.currentTimeMillis()); fireRetrievalStarted(re); fireRetrievalComplete(re); } }); } else { LOG.warn("no last created features that could be refreshed found"); // NOI18N } } /** * Determines the geometry type of the features of this service. * * @return the name of the geometrys most specific com.vividsolutions.jts.geom interface or * {@link AbstractFeatureService#UNKNOWN}, if the features can have different geometries */ public String getGeometryType() { return UNKNOWN; } /** * The number of features that should be shown on one page. (is used in the attribute table) * * @return the numbe rof eatures per page. Less than 1 shows all features on one page */ public int getMaxFeaturesPerPage() { return -1; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public String[] getCalculatedAttributes() { return new String[0]; } /** * Determines if this service has any restriction that forbids the retrieval of features for the given bounding box. * * @param box DOCUMENT ME! * * @return false, iff any restriction (e.g. the scale) prevents the retrieval of features for the given bounding * box */ public boolean isVisibleInBoundingBox(final XBoundingBox box) { final FeatureFactory ff = getFeatureFactory(); if (ff instanceof AbstractFeatureFactory) { final List<org.deegree.style.se.unevaluated.Style> styles = ((AbstractFeatureFactory)ff).getStyle( ((AbstractFeatureFactory)ff).layerName); if (styles != null) { for (final org.deegree.style.se.unevaluated.Style tempStyle : styles) { final org.deegree.style.se.unevaluated.Style filteredStyle = tempStyle.filter( CismapBroker.getInstance().getMappingComponent().getScaleDenominator()); final List rules = filteredStyle.getRules(); return !((rules == null) || rules.isEmpty()); } } } return true; } //~ Inner Classes ---------------------------------------------------------- /** * Feature Retrieval Thread started by the {@code retrieve()} operation. * * @version $Revision$, $Date$ */ protected class FeatureRetrievalWorker extends SwingWorker<List<FT>, FT> implements PropertyChangeListener { //~ Instance fields ---------------------------------------------------- private final long id = System.nanoTime(); //~ Constructors ------------------------------------------------------- /** * Creates a new FeatureRetrievalWorker object. */ public FeatureRetrievalWorker() { this.addPropertyChangeListener(this); } //~ Methods ------------------------------------------------------------ /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public long getId() { return this.id; } /** * DOCUMENT ME! * * @return DOCUMENT ME! * * @throws Exception DOCUMENT ME! */ @Override protected List<FT> doInBackground() throws Exception { if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("FRW[" + this.getId() + "]: doInBackground() started"); // NOI18N } } EventQueue.invokeLater(new Runnable() { @Override public void run() { final RetrievalEvent r = new RetrievalEvent(); r.setRequestIdentifier(getId()); r.setPercentageDone(-1); fireRetrievalStarted(r); } }); // check if canceled ....................................................... if (this.isCancelled()) { LOG.warn("FRW[" + this.getId() + "]: doInBackground() canceled"); // NOI18N return null; } // check if canceled ....................................................... final List<FT> features = retrieveFeatures(this); if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("FRW[" + this.getId() + "]: doInBackground() completed"); // NOI18N } } return features; } /** * DOCUMENT ME! */ @Override protected void done() { if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("FRW[" + this.getId() + "]: done()"); // NOI18N } } // check if canceled ....................................................... if (this.isCancelled()) { LOG.warn("FRW[" + this.getId() + "]: canceled (done)"); // NOI18N final RetrievalEvent re = new RetrievalEvent(); re.setRequestIdentifier(this.getId()); re.setPercentageDone(0); re.setHasErrors(false); fireRetrievalAborted(re); return; } // check if canceled ....................................................... try { List<FT> results = null; if (!this.isCancelled()) { results = this.get(); } if (results != null) { if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("FRW[" + this.getId() + "]: " + results.size() + " features created"); // NOI18N } } AbstractFeatureService.this.setRefreshNeeded(false); final RetrievalEvent re = new RetrievalEvent(); re.setRequestIdentifier(getId()); re.setIsComplete(true); re.setHasErrors(false); re.setRetrievedObject(results); fireRetrievalComplete(re); } else { LOG.warn("FRW[" + this.getId() + "]: FeatureRetrieverWorker brachte keine Ergebnisse (canceled=" + this.isCancelled() + ")"); // NOI18N // setErrorMessage("Feature Request brachte keine Ergebnisse"); final RetrievalEvent re = new RetrievalEvent(); re.setHasErrors(false); re.setRequestIdentifier(getId()); if (this.isCancelled()) { fireRetrievalAborted(re); } else { re.setRetrievedObject(new ArrayList<FT>()); fireRetrievalComplete(re); } } } catch (final Exception e) { LOG.error("FRW[" + this.getId() + "]: Fehler im FeatureRetrieverWorker (done): \n" + e.getMessage(), e); // NOI18N final RetrievalEvent re = new RetrievalEvent(); re.setRequestIdentifier(this.getId()); re.setPercentageDone(0); re.setHasErrors(true); re.setRetrievedObject(e.getMessage()); fireRetrievalError(re); } } /** * Fires a RetrievalEvent on progress update. * * @param evt DOCUMENT ME! */ @Override public void propertyChange(final PropertyChangeEvent evt) { if (evt.getPropertyName().equals("progress")) // NOI18N { final int progress = (Integer)evt.getNewValue(); // AbstractFeatureService.this.setProgress(progress); if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("FRW[" + this.getId() + "]: FeatureRetrieverWorker progress: " + progress); // NOI18N } } final RetrievalEvent re = new RetrievalEvent(); re.setRequestIdentifier(this.getId()); re.setIsComplete(progress != 100); re.setPercentageDone(progress); AbstractFeatureService.this.fireRetrievalProgress(re); } } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ @Override public String toString() { return String.valueOf(this.getId()); } } /** * Initialisiert den Layer. * * @version $Revision$, $Date$ */ protected class LayerInitWorker extends SwingWorker<Void, Void> implements PropertyChangeListener { //~ Instance fields ---------------------------------------------------- private final long id = System.nanoTime(); // private final long id = System.currentTimeMillis(); //~ Constructors ------------------------------------------------------- /** * Creates a new LayerInitWorker object. */ public LayerInitWorker() { this.addPropertyChangeListener(this); } //~ Methods ------------------------------------------------------------ /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public long getId() { return this.id; } /** * DOCUMENT ME! * * @return DOCUMENT ME! * * @throws Exception DOCUMENT ME! */ @Override protected Void doInBackground() throws Exception { if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("LIW[" + this.getId() + "]: doInBackground() started"); // NOI18N } } EventQueue.invokeLater(new Runnable() { @Override public void run() { final RetrievalEvent r = new RetrievalEvent(); r.setPercentageDone(-1); r.setRequestIdentifier(getId()); r.setInitialisationEvent(true); fireRetrievalStarted(r); } }); init(); return null; } /** * DOCUMENT ME! */ @Override protected void done() { AbstractFeatureService.this.setRefreshNeeded(false); if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("LIW[" + this.getId() + "]: done()"); // NOI18N } } // check if canceled ....................................................... if (isCancelled()) { if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("LIW[" + this.getId() + "]: canceled (done)"); // NOI18N } } setInitialized(false); final RetrievalEvent re = new RetrievalEvent(); re.setInitialisationEvent(true); re.setPercentageDone(0); re.setRequestIdentifier(this.getId()); re.setHasErrors(false); fireRetrievalAborted(re); return; } // check if canceled ....................................................... try { get(); if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("LIW[" + this.getId() + "]: finished"); // NOI18N } } AbstractFeatureService.this.setRefreshNeeded(false); final RetrievalEvent re = new RetrievalEvent(); re.setInitialisationEvent(true); re.setPercentageDone(100); re.setRequestIdentifier(getId()); re.setIsComplete(true); re.setHasErrors(false); re.setRetrievedObject(null); fireRetrievalComplete(re); } catch (final Exception e) { if (e.getCause() instanceof ShapeFileImportAborted) { // nothing to do. Layer was removed return; } LOG.error("LIW[" + this.getId() + "]: Fehler beim initalisieren des Layers: " + e.getMessage(), e); // NOI18N setInitialized(false); final RetrievalEvent re = new RetrievalEvent(); re.setInitialisationEvent(true); re.setPercentageDone(0); re.setRequestIdentifier(this.getId()); fireRetrievalStarted(re); re.setHasErrors(true); re.setRetrievedObject(e.getMessage()); fireRetrievalError(re); return; } setInitialized(true); layerInitWorker = null; // start initial retrieval retrieve(false); } /** * Fires a RetrievalEvent on progress update. * * @param evt DOCUMENT ME! */ @Override public void propertyChange(final PropertyChangeEvent evt) { if (evt.getPropertyName().equals("progress")) // NOI18N { final int progress = (Integer)evt.getNewValue(); // AbstractFeatureService.this.setProgress(progress); if (DEBUG) { if (LOG.isDebugEnabled()) { LOG.debug("LIW[" + this.getId() + "]: LayerInitWorker progress: " + progress); // NOI18N } } final RetrievalEvent re = new RetrievalEvent(); re.setInitialisationEvent(true); re.setRequestIdentifier(this.getId()); re.setIsComplete(progress != 100); re.setPercentageDone(progress); AbstractFeatureService.this.fireRetrievalProgress(re); } } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ @Override public String toString() { return String.valueOf(this.getId()); } } }