/* * (c) Copyright 2010-2011 AgileBirds * * This file is part of OpenFlexo. * * OpenFlexo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenFlexo 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>. * */ package org.openflexo.foundation.wkf.ws; import java.util.Enumeration; import java.util.Vector; import java.util.logging.Level; import java.util.logging.Logger; import org.openflexo.foundation.DataModification; import org.openflexo.foundation.DeletableObject; import org.openflexo.foundation.FlexoObservable; import org.openflexo.foundation.FlexoObserver; import org.openflexo.foundation.Inspectors; import org.openflexo.foundation.validation.DeletionFixProposal; import org.openflexo.foundation.validation.Validable; import org.openflexo.foundation.validation.ValidationError; import org.openflexo.foundation.validation.ValidationIssue; import org.openflexo.foundation.validation.ValidationRule; import org.openflexo.foundation.wkf.FlexoLevel; import org.openflexo.foundation.wkf.FlexoProcess; import org.openflexo.foundation.wkf.LevelledObject; import org.openflexo.foundation.wkf.WKFObject; import org.openflexo.foundation.wkf.dm.ObjectVisibilityChanged; import org.openflexo.foundation.wkf.dm.PortMapInserted; import org.openflexo.foundation.wkf.dm.PortMapRegisteryOrientationChanged; import org.openflexo.foundation.wkf.dm.PortMapRegisteryRemoved; import org.openflexo.foundation.wkf.dm.PortMapRemoved; import org.openflexo.foundation.wkf.node.SubProcessNode; import org.openflexo.foundation.xml.FlexoProcessBuilder; import org.openflexo.inspector.InspectableObject; /** * A PortMapRegistery is attached to a SubProcessNode and contains all the portmaps used in the context of WebServices * * @author sguerin * */ public final class PortMapRegistery extends WKFObject implements InspectableObject, LevelledObject, DeletableObject, FlexoObserver { private static final Logger logger = Logger.getLogger(PortMapRegistery.class.getPackage().getName()); public static final int NORTH = 0; public static final int EAST = 1; public static final int SOUTH = 2; public static final int WEST = 3; // ========================================================================== // ============================= Variables // ================================== // ========================================================================== private SubProcessNode _subProcessNode; private int _orientation = NORTH; private Vector<FlexoPortMap> _portMaps; // ========================================================================== // ============================= Constructor // ================================ // ========================================================================== /** * Constructor used during deserialization */ public PortMapRegistery(FlexoProcessBuilder builder) { this(builder.process); initializeDeserialization(builder); } /** * Default constructor */ public PortMapRegistery(FlexoProcess process) { super(process); _portMaps = new Vector<FlexoPortMap>(); } /** * @param portRegistery */ public PortMapRegistery(SubProcessNode subProcessNode) { this(subProcessNode.getProcess()); setSubProcessNode(subProcessNode); setOrientation(NORTH); } @Override public String getFullyQualifiedName() { return getProcess().getFullyQualifiedName() + ".PORTMAP_REGISTERY"; } public SubProcessNode getSubProcessNode() { return _subProcessNode; } public void setSubProcessNode(SubProcessNode subProcessNode) { if (_subProcessNode != subProcessNode) { if (_subProcessNode != null) { if (_subProcessNode.getActiveServiceInterface() != null) { _subProcessNode.getActiveServiceInterface().deleteObserver(this); } } } _subProcessNode = subProcessNode; } /** * refactoring of this method: lookupRegistery instead of lookupPortRegistry * */ public void lookupServiceInterface() { if (logger.isLoggable(Level.FINE)) { logger.fine("lookupServiceInterface"); } getServiceInterface(); updateFromServiceInterface(); } public ServiceInterface getServiceInterface() { if (getSubProcessNode() != null && getSubProcessNode().getSubProcess() != null) { if (getSubProcessNode().getActiveServiceInterface() != null) { getSubProcessNode().getActiveServiceInterface().addObserver(this); } else { if (logger.isLoggable(Level.WARNING)) { logger.warning("No related ServiceInterface !!!!"); } } return getSubProcessNode().getActiveServiceInterface(); } return null; } /** * Return a Vector of all embedded WKFObjects * * @return a Vector of WKFObject instances */ @Override public Vector<WKFObject> getAllEmbeddedWKFObjects() { Vector<WKFObject> returned = new Vector<WKFObject>(); returned.add(this); for (Enumeration<FlexoPortMap> e = getPortMaps().elements(); e.hasMoreElements();) { FlexoPortMap portMap = e.nextElement(); returned.addAll(portMap.getAllEmbeddedWKFObjects()); } return returned; } @Override public Vector<WKFObject> getAllEmbeddedDeleted() { return getAllEmbeddedWKFObjects(); } public Vector<FlexoPortMap> getPortMaps() { return _portMaps; } public void reorderPortmaps(FlexoPortMap reorderedPortMap, FlexoPortMap after) { _portMaps.remove(reorderedPortMap); int index = _portMaps.indexOf(after); _portMaps.insertElementAt(reorderedPortMap, index + 1); } public Vector<FlexoPortMap> getVisiblePortMaps() { Vector<FlexoPortMap> v = new Vector<FlexoPortMap>(_portMaps.size() + 1); Enumeration en = _portMaps.elements(); while (en.hasMoreElements()) { FlexoPortMap map = (FlexoPortMap) en.nextElement(); if (!map.getIsHidden()) { v.add(map); } } return v; } public void setPortMaps(Vector<FlexoPortMap> portMaps) { _portMaps = portMaps; } public void addToPortMaps(FlexoPortMap aPortMap) { // logger.info(">>>>>> addToPortMaps("+aPortMap.getPortName()+","+aPortMap.getOperation()+")"); if (!_portMaps.contains(aPortMap)) { _portMaps.add(aPortMap); aPortMap.setPortMapRegistery(this); aPortMap.addObserver(this); setChanged(); notifyObservers(new PortMapInserted(aPortMap)); if (getProcess() != null) { getProcess().clearCachedObjects(); } } } public void removeFromPortMaps(FlexoPortMap aPortMap) { // logger.info(">>>>>> removeFromPortMaps("+aPortMap+")"); if (_portMaps.contains(aPortMap)) { _portMaps.remove(aPortMap); aPortMap.setPortMapRegistery(null); aPortMap.deleteObserver(this); setChanged(); notifyObservers(new PortMapRemoved(aPortMap)); if (getProcess() != null) { getProcess().clearCachedObjects(); } } } public void updateFromServiceInterface() { if (logger.isLoggable(Level.FINE)) { logger.fine("updateFromServiceInterface()"); } Vector<FlexoPortMap> portMapsToDelete = new Vector<FlexoPortMap>(getPortMaps()); if (getServiceInterface() != null) { // Vector operations = getServiceInterface().getOperations(); // if (logger.isLoggable(Level.FINE)) logger.fine("Operations of serviceInterface:"+operations); for (Enumeration e = getServiceInterface().getSortedOperations(); e.hasMoreElements();) { ServiceOperation op = (ServiceOperation) e.nextElement(); if (portMapForOperation(op) == null) { // Creates the portmap FlexoPortMap newPortMap = new FlexoPortMap(op, getProcess()); newPortMap.setIndex(op.getPort().getIndex()); addToPortMaps(newPortMap); } else { portMapsToDelete.remove(portMapForOperation(op)); } if (portMapForOperation(op) != null) { portMapForOperation(op).registerUnderSubProcessNode(); } } } else { if (logger.isLoggable(Level.WARNING)) { logger.warning("No related ServiceInterface ! !"); } } for (Enumeration<FlexoPortMap> e = portMapsToDelete.elements(); e.hasMoreElements();) { FlexoPortMap portMap = e.nextElement(); if (logger.isLoggable(Level.FINE)) { logger.fine("Remove portmap " + portMap.getPortName()); } portMap.delete(); } } private FlexoPortMap portMapForOperation(ServiceOperation op) { for (Enumeration e = getPortMaps().elements(); e.hasMoreElements();) { FlexoPortMap portMap = (FlexoPortMap) e.nextElement(); if (portMap.getOperation() == op) { return portMap; } } return null; } @Override public void update(FlexoObservable observable, DataModification dataModification) { if (logger.isLoggable(Level.FINE)) { logger.fine("update PortMapRegistry" + observable + " - " + dataModification.getClass().getName()); } if (!isSerializing()) { if (observable instanceof ServiceInterface) { updateFromServiceInterface(); } } if (observable instanceof FlexoPortMap && dataModification instanceof ObjectVisibilityChanged) { if (((ObjectVisibilityChanged) dataModification).isVisible()) { setIsHidden(false); } else { hideIfRequired(); } } } private void hideIfRequired() { boolean hide = true; for (FlexoPortMap map : getPortMaps()) { if (map.getIsVisible()) { hide = false; break; } } if (hide) { setIsHidden(true); } } @Override public final void delete() { if (logger.isLoggable(Level.FINE)) { logger.fine("delete() in PortMapRegistery"); } for (Enumeration e = ((Vector) getPortMaps().clone()).elements(); e.hasMoreElements();) { FlexoPortMap portMap = (FlexoPortMap) e.nextElement(); portMap.delete(); } super.delete(); setChanged(); notifyObservers(new PortMapRegisteryRemoved(this)); if (getSubProcessNode() != null) { getSubProcessNode().setPortMapRegistery(null); setSubProcessNode(null); } setProcess(null); deleteObservers(); } @Override public String getInspectorName() { return Inspectors.WKF.PORTMAP_REGISTERY_INSPECTOR; } @Override public FlexoLevel getLevel() { return FlexoLevel.ACTIVITY; } public int getOrientation() { return _orientation; } public void setOrientation(int orientation) { int oldOrientation = _orientation; if (oldOrientation != orientation) { _orientation = orientation; setChanged(); notifyObservers(new PortMapRegisteryOrientationChanged(oldOrientation, orientation)); } } // ========================================================================== // ============================= Validation // ================================= // ========================================================================== /** * must refer to a serviceInterface */ public static class PortMapRegisteryMustReferToServiceInterface extends ValidationRule { public PortMapRegisteryMustReferToServiceInterface() { super(PortMapRegistery.class, "portmap_registery_must_be_linked_to_a_service_interface"); } @Override public ValidationIssue applyValidation(final Validable object) { final PortMapRegistery portMapRegistery = (PortMapRegistery) object; if (portMapRegistery.getServiceInterface() == null) { ValidationError error = new ValidationError(this, object, "portmap_registery_is_not_linked_to_a_service_interface"); error.addToFixProposals(new DeletionFixProposal("delete_this_portmap_registery")); return error; } return null; } } /** * Overrides getClassNameKey * * @see org.openflexo.foundation.FlexoModelObject#getClassNameKey() */ @Override public String getClassNameKey() { return "port_map_registery"; } public FlexoPortMap getPortMapForPort(FlexoPort flexoPort) { for (FlexoPortMap portMap : _portMaps) { if (portMap.getOperation().getPort() == flexoPort) { return portMap; } } return null; } public Vector<FlexoPortMap> getAllNewPortmaps() { Vector<FlexoPortMap> returned = new Vector<FlexoPortMap>(); for (FlexoPortMap pm : getPortMaps()) { if (pm.getOperation().getPort() instanceof NewPort) { returned.add(pm); } } return returned; } public Vector<FlexoPortMap> getAllDeletePortmaps() { Vector<FlexoPortMap> returned = new Vector<FlexoPortMap>(); for (FlexoPortMap pm : getPortMaps()) { if (pm.getOperation().getPort() instanceof DeletePort) { returned.add(pm); } } return returned; } public Vector<FlexoPortMap> getAllOutPortmaps() { Vector<FlexoPortMap> returned = new Vector<FlexoPortMap>(); for (FlexoPortMap pm : getPortMaps()) { if (pm.getOperation().getPort() instanceof OutPort) { returned.add(pm); } } return returned; } public boolean getIsHidden() { return !getIsVisible(true); } public void setIsHidden(boolean hidePortMap) { setIsVisible(!hidePortMap); } }