Java tutorial
/* * Copyright 2005-2008 Julien Ponge <http://julien.ponge.info/>. * Copyright 2005-2008 Universite Blaise Pascal, LIMOS, Clermont-Ferrand, France. * Copyright 2005-2008 The University of New South Wales, Sydney, Australia. * * This file is part of ServiceMosaic Protocols <http://servicemosaic.isima.fr/>. * * ServiceMosaic Protocols is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * ServiceMosaic Protocols is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with ServiceMosaic Protocols. If not, see <http://www.gnu.org/licenses/>. */ package fr.isima.ponge.wsprotocol.gefeditor.editparts.propertysources; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.io.SAXReader; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.ui.views.properties.ComboBoxPropertyDescriptor; import org.eclipse.ui.views.properties.IPropertyDescriptor; import org.eclipse.ui.views.properties.IPropertySource; import org.eclipse.ui.views.properties.TextPropertyDescriptor; import fr.isima.ponge.wsprotocol.OperationKind; import fr.isima.ponge.wsprotocol.Polarity; import fr.isima.ponge.wsprotocol.StandardExtraProperties; import fr.isima.ponge.wsprotocol.gefeditor.Messages; import fr.isima.ponge.wsprotocol.impl.MessageImpl; import fr.isima.ponge.wsprotocol.impl.OperationImpl; /** * The property source for operations (actually works on the message carried by the operation). * * @author Julien Ponge (ponge@isima.fr) */ public class OperationPropertySource implements IPropertySource { /** * Id for the WSDL problems resource marker. */ private static final String WSDL_PROBLEM_MARKER_ID = "gef.editor.wsdl.io.problem"; //$NON-NLS-1$ /** * The operation name property ... name :-) */ protected static final String OPERATION_NAME_PROPERTY = "operation.name"; //$NON-NLS-1$ /** * The message polarity property name. */ protected static final String MESSAGE_POLARITY_PROPERTY = "message.polarity"; //$NON-NLS-1$ /** * The message name property name. */ protected static final String MESSAGE_NAME_PROPERTY = "message.name"; //$NON-NLS-1$ /** * The operation kind property name. */ protected static final String OPERATION_KIND_PROPERTY = "operation.kind"; //$NON-NLS-1$ /** * The operation temporal constraint property name. */ protected static final String TEMPORAL_CONSTRAINT_PROPERTY = "temporal.constraint"; //$NON-NLS-1$ /** * The operation */ protected OperationImpl operation; /** * The message. */ protected MessageImpl message; /** * The (optional) WSDL document location. */ protected String wsdlLocation; /** * The associated protocol file descriptor. */ protected IFile protocolFile; /** * WSDL messages, as an array. */ protected String[] wsdlMessages; /** * WSDL messages, as a list. */ protected List wsdlMessagesList; /** * The properties descriptors. */ protected IPropertyDescriptor[] propertyDescriptors = new IPropertyDescriptor[5]; /** * Constructs a new operations properties source. * * @param operation * The operation. * @param wsdlLocation * The WSDL document location. * @param protocolFile * The associated protocol file. */ public OperationPropertySource(OperationImpl operation, String wsdlLocation, IFile protocolFile) { super(); this.operation = operation; this.message = (MessageImpl) operation.getMessage(); this.wsdlLocation = wsdlLocation; this.protocolFile = protocolFile; updatePropertyDescriptors(); } /** * Creates or updates the property descriptors. If the protocol has a WSDL that can be parsed, * then the messages names will be presented in a combo. */ protected void updatePropertyDescriptors() { propertyDescriptors[0] = new TextPropertyDescriptor(OPERATION_NAME_PROPERTY, Messages.operationName); List messages = getWSDLMessagesNames(); if (messages.equals(Collections.EMPTY_LIST) || message.getPolarity().equals(Polarity.NULL)) { propertyDescriptors[1] = new TextPropertyDescriptor(MESSAGE_NAME_PROPERTY, Messages.messageName); } else { Object[] vals = messages.toArray(); wsdlMessages = new String[vals.length]; for (int i = 0; i < vals.length; ++i) { wsdlMessages[i] = (String) vals[i]; } wsdlMessagesList = messages; propertyDescriptors[1] = new ComboBoxPropertyDescriptor(MESSAGE_NAME_PROPERTY, Messages.messageName, wsdlMessages); } propertyDescriptors[2] = new ComboBoxPropertyDescriptor(MESSAGE_POLARITY_PROPERTY, Messages.messagePolarity, new String[] { Messages.input, Messages.output, Messages.none }); propertyDescriptors[3] = new ComboBoxPropertyDescriptor(OPERATION_KIND_PROPERTY, Messages.operationKind, new String[] { Messages.explicit, Messages.implicit }); propertyDescriptors[4] = new TextPropertyDescriptor(TEMPORAL_CONSTRAINT_PROPERTY, Messages.temporalConstraint); } /* * Used to cache the WSDL parsing results. */ private static Map cachedParsings = new HashMap(); /** * Trys to get the messages names from a WSDL document. * * @return The list of the messages names or <code>Collections.EMPTY_LIST</code>. */ protected List getWSDLMessagesNames() { // No WSDL if (wsdlLocation == null || "".equals(wsdlLocation)) //$NON-NLS-1$ { return Collections.EMPTY_LIST; } // Cached parsings if (cachedParsings.containsKey(wsdlLocation)) { return (List) cachedParsings.get(wsdlLocation); } // Parse the WSDL cleanProblemMarkers(WSDL_PROBLEM_MARKER_ID); List names = new ArrayList(); try { SAXReader reader = new SAXReader(); Document document = reader.read(new URL(wsdlLocation)); Iterator nodesIt = document.selectNodes("//*[local-name()='message']/@name").iterator(); while (nodesIt.hasNext()) { Attribute attr = (Attribute) nodesIt.next(); names.add(attr.getValue()); } Collections.sort(names); } catch (MalformedURLException e) { reportWSDLProblem(); } catch (DocumentException e) { reportWSDLProblem(); } cachedParsings.put(wsdlLocation, (names.size() > 0) ? names : Collections.EMPTY_LIST); return (names.size() > 0) ? names : Collections.EMPTY_LIST; } /** * Removes the problem markers on the file resource (if any). * @param markerId The problem marker ID. */ private void cleanProblemMarkers(String markerId) { try { IMarker[] problems = protocolFile.findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_ONE); for (int i = 0; i < problems.length; ++i) { if (problems[i].exists() && problems[i].getAttributes().containsKey(markerId)) { problems[i].delete(); } } } catch (CoreException e) { e.printStackTrace(); } } /** * Reports a WSDL problem on the file resource. */ private void reportWSDLProblem() { try { IMarker marker = protocolFile.createMarker(IMarker.PROBLEM); if (marker.exists()) { marker.setAttribute(IMarker.TRANSIENT, true); marker.setAttribute(IMarker.MESSAGE, Messages.invalidWSDL); marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR); marker.setAttribute(WSDL_PROBLEM_MARKER_ID, WSDL_PROBLEM_MARKER_ID); } } catch (CoreException e) { e.printStackTrace(); } } /* * (non-Javadoc) * * @see org.eclipse.ui.views.properties.IPropertySource#getEditableValue() */ public Object getEditableValue() { return this; } /* * (non-Javadoc) * * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyDescriptors() */ public IPropertyDescriptor[] getPropertyDescriptors() { return propertyDescriptors; } /* * (non-Javadoc) * * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyValue(java.lang.Object) */ public Object getPropertyValue(Object id) { if (id.equals(MESSAGE_NAME_PROPERTY)) { if (wsdlMessages == null) { return message.getName(); } else { int index = wsdlMessagesList.indexOf(message.getName()); if (index == -1) { index = 0; message.setName((String) wsdlMessagesList.get(index)); } return new Integer(index); } } else if (id.equals(MESSAGE_POLARITY_PROPERTY)) { Polarity p = message.getPolarity(); if (p.equals(Polarity.POSITIVE)) { return new Integer(0); } else if (p.equals(Polarity.NEGATIVE)) { return new Integer(1); } else if (p.equals(Polarity.NULL)) { return new Integer(2); } } else if (id.equals(OPERATION_NAME_PROPERTY)) { return operation.getName(); } else if (id.equals(OPERATION_KIND_PROPERTY)) { OperationKind kind = operation.getOperationKind(); if (kind.equals(OperationKind.EXPLICIT)) { return new Integer(0); } else if (kind.equals(OperationKind.IMPLICIT)) { return new Integer(1); } } else if (id.equals(TEMPORAL_CONSTRAINT_PROPERTY)) { String constraint = (String) operation.getExtraProperty(StandardExtraProperties.TEMPORAL_CONSTRAINT); if (constraint == null) { return ""; //$NON-NLS-1$ } return constraint; } return null; } /* * (non-Javadoc) * * @see org.eclipse.ui.views.properties.IPropertySource#isPropertySet(java.lang.Object) */ public boolean isPropertySet(Object id) { // All properties are mandatory in the model return true; } /* * (non-Javadoc) * * @see org.eclipse.ui.views.properties.IPropertySource#resetPropertyValue(java.lang.Object) */ public void resetPropertyValue(Object id) { // Nothing to do here ... } /* * (non-Javadoc) * * @see org.eclipse.ui.views.properties.IPropertySource#setPropertyValue(java.lang.Object, * java.lang.Object) */ public void setPropertyValue(Object id, Object value) { if (id.equals(MESSAGE_NAME_PROPERTY)) { if (wsdlMessages == null) { message.setName((String) value); } else { message.setName((String) wsdlMessagesList.get(((Integer) value).intValue())); } } else if (id.equals(MESSAGE_POLARITY_PROPERTY)) { if (value.equals(Integer.valueOf("0"))) //$NON-NLS-1$ { message.setPolarity(Polarity.POSITIVE); } else if (value.equals(Integer.valueOf("1"))) //$NON-NLS-1$ { message.setPolarity(Polarity.NEGATIVE); } else if (value.equals(Integer.valueOf("2"))) //$NON-NLS-1$ { message.setPolarity(Polarity.NULL); } //updatePropertyDescriptors(); } else if (id.equals(OPERATION_NAME_PROPERTY)) { operation.setName((String) value); } else if (id.equals(OPERATION_KIND_PROPERTY)) { if (value.equals(Integer.valueOf("0"))) //$NON-NLS-1$ { operation.setOperationKind(OperationKind.EXPLICIT); } else if (value.equals(Integer.valueOf("1"))) //$NON-NLS-1$ { operation.setOperationKind(OperationKind.IMPLICIT); message.setPolarity(Polarity.NULL); } } else if (id.equals(TEMPORAL_CONSTRAINT_PROPERTY)) { String constraint = (String) value; operation.putExtraProperty(StandardExtraProperties.TEMPORAL_CONSTRAINT, constraint); } } }