/******************************************************************************* * Copyright (c) 2010 protos software gmbh (http://www.protos.de). * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * CONTRIBUTORS: * Thomas Schuetz and Henrik Rentz-Reichert (initial contribution) * *******************************************************************************/ package org.eclipse.etrice.core.naming; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.etrice.core.room.ActorClass; import org.eclipse.etrice.core.room.ActorContainerClass; import org.eclipse.etrice.core.room.ActorContainerRef; import org.eclipse.etrice.core.room.ActorRef; import org.eclipse.etrice.core.room.Binding; import org.eclipse.etrice.core.room.BindingEndPoint; import org.eclipse.etrice.core.room.ChoicePoint; import org.eclipse.etrice.core.room.DataClass; import org.eclipse.etrice.core.room.InitialTransition; import org.eclipse.etrice.core.room.LayerConnection; import org.eclipse.etrice.core.room.LogicalSystem; import org.eclipse.etrice.core.room.NonInitialTransition; import org.eclipse.etrice.core.room.Port; import org.eclipse.etrice.core.room.ProtocolClass; import org.eclipse.etrice.core.room.RefSAPoint; import org.eclipse.etrice.core.room.RelaySAPoint; import org.eclipse.etrice.core.room.RoomClass; import org.eclipse.etrice.core.room.RoomFactory; import org.eclipse.etrice.core.room.RoomModel; import org.eclipse.etrice.core.room.RoomPackage; import org.eclipse.etrice.core.room.SAPoint; import org.eclipse.etrice.core.room.SPPRef; import org.eclipse.etrice.core.room.SPPoint; import org.eclipse.etrice.core.room.State; import org.eclipse.etrice.core.room.StateGraph; import org.eclipse.etrice.core.room.StructureClass; import org.eclipse.etrice.core.room.SubSystemClass; import org.eclipse.etrice.core.room.SubSystemRef; import org.eclipse.etrice.core.room.TrPoint; import org.eclipse.etrice.core.room.Transition; import org.eclipse.etrice.core.room.util.RoomSwitch; import org.eclipse.xtext.resource.IFragmentProvider; public class RoomFragmentProvider implements IFragmentProvider { private class PathProvider extends RoomSwitch<String> { @Override public String caseRoomClass(RoomClass rc) { return rc.getName(); } @Override public String casePort(Port port) { return doSwitch(port.eContainer())+SEP+port.getName(); } @Override public String caseSPPRef(SPPRef spp) { return doSwitch(spp.eContainer())+SEP+spp.getName(); } @Override public String caseActorContainerRef(ActorContainerRef acr) { return doSwitch(acr.eContainer())+SEP+acr.getName(); } @Override public String caseBinding(Binding bi) { return doSwitch(bi.eContainer())+SEP +caseBindingEndPoint(bi.getEndpoint1())+BIND_SEP +caseBindingEndPoint(bi.getEndpoint2()); } @Override public String caseBindingEndPoint(BindingEndPoint ep) { String loc = ep.getActorRef()==null? LOCAL:ep.getActorRef().getName(); return ep.getPort().getName()+EP_SEP+loc; } @Override public String caseLayerConnection(LayerConnection bi) { return doSwitch(bi.eContainer())+SEP +caseSAPoint(bi.getFrom())+CONN_SEP +caseSPPoint(bi.getTo()); } @Override public String caseSAPoint(SAPoint sapt) { if (sapt instanceof RefSAPoint) return ((RefSAPoint) sapt).getRef().getName(); else if (sapt instanceof RelaySAPoint) return ((RelaySAPoint) sapt).getRelay().getName(); assert(false): "unexpectd sub type"; return null; } @Override public String caseSPPoint(SPPoint sppt) { return sppt.getRef().getName()+EP_SEP+sppt.getService().getName(); } @Override public String caseState(State s) { // going up two steps in the containment hierarchy either hits another state or a RoomClass return doSwitch(s.eContainer().eContainer())+SEP+s.getName(); } @Override public String caseTrPoint(TrPoint trp) { // going up two steps in the containment hierarchy either hits a state or a RoomClass return doSwitch(trp.eContainer().eContainer())+SEP+trp.getName(); } @Override public String caseChoicePoint(ChoicePoint cp) { // going up two steps in the containment hierarchy either hits a state or a RoomClass return doSwitch(cp.eContainer().eContainer())+SEP+cp.getName(); } @Override public String caseInitialTransition(InitialTransition t) { // going up two steps in the containment hierarchy either hits a state or a RoomClass return doSwitch(t.eContainer().eContainer())+SEP+INIT_TRANS; } @Override public String caseNonInitialTransition(NonInitialTransition t) { // the transition name is optional in the ROOM DSL but will be automatically assigned // by the Behavior Editor // going up two steps in the containment hierarchy either hits a state or a RoomClass return doSwitch(t.eContainer().eContainer())+SEP+t.getName(); } @Override public String caseStateGraph(StateGraph sg) { // going up one step in the containment hierarchy either hits a state or a RoomClass return doSwitch(sg.eContainer())+SEP+STATE_GRAPH; } } private static final char SEP = '$'; private static final char BIND_SEP = '-'; private static final char CONN_SEP = '-'; private static final String INIT_TRANS = "initial"; private static final String STATE_GRAPH = "sg"; private static final char EP_SEP = '!'; private static final String LOCAL = "."; private static final char TYPE_SEP = ':'; private PathProvider pathProvider = new PathProvider(); @Override public String getFragment(EObject obj, Fallback fallback) { String path = pathProvider.doSwitch(obj); if (path!=null) return obj.eClass().getName()+TYPE_SEP+path; return fallback.getFragment(obj); } @Override public EObject getEObject(Resource resource, String fragment, Fallback fallback) { RoomModel model = (RoomModel) resource.getContents().get(0); EObject result = getEObject(model, fragment); if (result!=null) return result; return fallback.getEObject(fragment); } public static boolean isPort(EObject obj) { URI uri = EcoreUtil.getURI(obj); return uri!=null && uri.fragment()!=null && uri.fragment().startsWith(RoomPackage.eINSTANCE.getPort().getName()); } public static boolean isSPP(EObject obj) { URI uri = EcoreUtil.getURI(obj); return uri!=null && uri.fragment()!=null && uri.fragment().startsWith(RoomPackage.eINSTANCE.getSPPRef().getName()); } public static boolean isBinding(EObject obj) { URI uri = EcoreUtil.getURI(obj); return uri!=null && uri.fragment()!=null && uri.fragment().startsWith(RoomPackage.eINSTANCE.getBinding().getName()); } public static boolean isLayerConnection(EObject obj) { URI uri = EcoreUtil.getURI(obj); return uri!=null && uri.fragment()!=null && uri.fragment().startsWith(RoomPackage.eINSTANCE.getLayerConnection().getName()); } public static boolean isRef(EObject obj) { URI uri = EcoreUtil.getURI(obj); if (uri!=null && uri.fragment()!=null) { if (uri.fragment().startsWith(RoomPackage.eINSTANCE.getActorContainerRef().getName())) return true; if (uri.fragment().startsWith(RoomPackage.eINSTANCE.getActorRef().getName())) return true; } return false; } public static boolean isState(EObject obj) { URI uri = EcoreUtil.getURI(obj); if (uri!=null && uri.fragment()!=null) { if (uri.fragment().startsWith(RoomPackage.eINSTANCE.getBaseState().getName())) return true; if (uri.fragment().startsWith(RoomPackage.eINSTANCE.getRefinedState().getName())) return true; } return false; } public static boolean isTrPoint(EObject obj) { URI uri = EcoreUtil.getURI(obj); if (uri!=null && uri.fragment()!=null) { if (uri.fragment().startsWith(RoomPackage.eINSTANCE.getTransitionPoint().getName())) return true; if (uri.fragment().startsWith(RoomPackage.eINSTANCE.getEntryPoint().getName())) return true; if (uri.fragment().startsWith(RoomPackage.eINSTANCE.getExitPoint().getName())) return true; } return false; } public static boolean isChoicePoint(EObject obj) { URI uri = EcoreUtil.getURI(obj); return uri!=null && uri.fragment()!=null && uri.fragment().startsWith(RoomPackage.eINSTANCE.getChoicePoint().getName()); } public static boolean isStateGraph(EObject obj) { URI uri = EcoreUtil.getURI(obj); return uri!=null && uri.fragment()!=null && uri.fragment().startsWith(RoomPackage.eINSTANCE.getStateGraph().getName()); } public static boolean isTransition(EObject obj) { URI uri = EcoreUtil.getURI(obj); if (uri!=null && uri.fragment()!=null) { if (uri.fragment().startsWith(RoomPackage.eINSTANCE.getInitialTransition().getName())) return true; if (uri.fragment().startsWith(RoomPackage.eINSTANCE.getContinuationTransition().getName())) return true; if (uri.fragment().startsWith(RoomPackage.eINSTANCE.getCPBranchTransition().getName())) return true; if (uri.fragment().startsWith(RoomPackage.eINSTANCE.getTriggeredTransition().getName())) return true; } return false; } public static boolean isStructureClass(EObject obj) { URI uri = EcoreUtil.getURI(obj); if (uri!=null && uri.fragment()!=null) { if (uri.fragment().startsWith(RoomPackage.eINSTANCE.getActorClass().getName())) return true; if (uri.fragment().startsWith(RoomPackage.eINSTANCE.getSubSystemClass().getName())) return true; if (uri.fragment().startsWith(RoomPackage.eINSTANCE.getLogicalSystem().getName())) return true; } return false; } private EObject getEObject(RoomModel model, String fragment) { int begin = 0; int end = fragment.indexOf(TYPE_SEP); if (end<0) return null; String type = fragment.substring(begin, end); begin = end+1; end = fragment.indexOf(SEP, begin); if (end<0) end = fragment.length(); String className = fragment.substring(begin, end); RoomClass rc = getRoomClass(model, className); if (type.equals(RoomPackage.eINSTANCE.getDataClass().getName())) { return rc; } else if (type.equals(RoomPackage.eINSTANCE.getProtocolClass().getName())) { return rc; } else if (type.equals(RoomPackage.eINSTANCE.getActorClass().getName())) { return rc; } else if (type.equals(RoomPackage.eINSTANCE.getSubSystemClass().getName())) { return rc; } else if (type.equals(RoomPackage.eINSTANCE.getLogicalSystem().getName())) { return rc; } if (end<fragment.length()) { String remainder = fragment.substring(end+1, fragment.length()); if (type.equals(RoomPackage.eINSTANCE.getPort().getName())) { return getPort(rc, remainder); } else if (type.equals(RoomPackage.eINSTANCE.getSPPRef().getName())) { return getSPP(rc, remainder); } else if (type.equals(RoomPackage.eINSTANCE.getSubSystemRef().getName()) || type.equals(RoomPackage.eINSTANCE.getActorRef().getName())) { return getActorContainerRef(rc, remainder); } else if (type.equals(RoomPackage.eINSTANCE.getBinding().getName())) { return getBinding(rc, remainder); } else if (type.equals(RoomPackage.eINSTANCE.getLayerConnection().getName())) { return getLayerConnection(rc, remainder); } else if (type.equals(RoomPackage.eINSTANCE.getBaseState().getName()) || type.equals(RoomPackage.eINSTANCE.getRefinedState().getName())) { return getState(rc, remainder); } else if (type.equals(RoomPackage.eINSTANCE.getTransitionPoint().getName()) || type.equals(RoomPackage.eINSTANCE.getEntryPoint().getName()) || type.equals(RoomPackage.eINSTANCE.getExitPoint().getName())) { return getTrPoint(rc, remainder); } else if (type.equals(RoomPackage.eINSTANCE.getChoicePoint().getName())) { return getChoicePoint(rc, remainder); } else if (type.equals(RoomPackage.eINSTANCE.getInitialTransition().getName())) { return getInitialTransition(rc, remainder); } else if (type.equals(RoomPackage.eINSTANCE.getContinuationTransition().getName()) || type.equals(RoomPackage.eINSTANCE.getCPBranchTransition().getName()) || type.equals(RoomPackage.eINSTANCE.getTriggeredTransition().getName())) { return getTransition(rc, remainder); } else if (type.equals(RoomPackage.eINSTANCE.getStateGraph().getName())) { return getStateGraph(rc, remainder); } } return null; } private Transition getTransition(RoomClass rc, String remainder) { StateGraph sg = getStateGraph(rc, remainder); int begin = remainder.lastIndexOf(SEP); if (begin<0) begin = 0; else ++begin; String name = remainder.substring(begin, remainder.length()); for (Transition t : sg.getTransitions()) { if (t.getName().equals(name)) { return t; } } return null; } private InitialTransition getInitialTransition(RoomClass rc, String remainder) { StateGraph sg = getStateGraph(rc, remainder); int begin = remainder.lastIndexOf(SEP); if (begin<0) begin = 0; else ++begin; String name = remainder.substring(begin, remainder.length()); if (name.equals(INIT_TRANS)) { for (Transition t : sg.getTransitions()) { if (t instanceof InitialTransition) return (InitialTransition) t; } } return null; } private ChoicePoint getChoicePoint(RoomClass rc, String remainder) { StateGraph sg = getStateGraph(rc, remainder); int begin = remainder.lastIndexOf(SEP); if (begin<0) begin = 0; else ++begin; String name = remainder.substring(begin, remainder.length()); for (ChoicePoint cp : sg.getChPoints()) { if (cp.getName().equals(name)) { return cp; } } return null; } private TrPoint getTrPoint(RoomClass rc, String remainder) { StateGraph sg = getStateGraph(rc, remainder); int begin = remainder.lastIndexOf(SEP); if (begin<0) begin = 0; else ++begin; String name = remainder.substring(begin, remainder.length()); for (TrPoint tp : sg.getTrPoints()) { if (tp.getName().equals(name)) { return tp; } } return null; } private State getState(RoomClass rc, String remainder) { StateGraph sg = getStateGraph(rc, remainder); int begin = remainder.lastIndexOf(SEP); if (begin<0) begin = 0; else ++begin; String name = remainder.substring(begin, remainder.length()); for (State s : sg.getStates()) { if (s.getName().equals(name)) { return s; } } return null; } private StateGraph getStateGraph(RoomClass rc, String remainder) { if (rc instanceof ActorClass) { StateGraph sg = ((ActorClass) rc).getStateMachine(); if (sg==null) ((ActorClass) rc).setStateMachine(RoomFactory.eINSTANCE.createStateGraph()); int begin = 0; int end = remainder.indexOf(SEP); while (end>=0) { String name = remainder.substring(begin, end); boolean found = false; for (State s : sg.getStates()) { if (s.getName().equals(name)) { sg = s.getSubgraph(); found = true; break; } } if (!found) return null; begin = end+1; end = remainder.indexOf(SEP, begin); } return sg; } return null; } private EObject getBinding(RoomClass rc, String name) { int pos = name.indexOf(BIND_SEP); if (pos<0) return null; if (rc instanceof StructureClass) { String ep1name = name.substring(0, pos); String ep2name = name.substring(pos+1, name.length()); StructureClass sc = (StructureClass) rc; BindingEndPoint ep1 = getEndpoint(sc, ep1name); BindingEndPoint ep2 = getEndpoint(sc, ep2name); for (Binding bi : sc.getBindings()) { if (isEP(bi.getEndpoint1(),ep1) && isEP(bi.getEndpoint2(),ep2)) return bi; if (isEP(bi.getEndpoint1(),ep2) && isEP(bi.getEndpoint2(),ep1)) return bi; } } return null; } private boolean isEP(BindingEndPoint a, BindingEndPoint b) { if (a.getPort().getName().equals(b.getPort().getName())) { if (a.getActorRef()==null && b.getActorRef()==null) return true; if (a.getActorRef()!=null && b.getActorRef()!=null) if (a.getActorRef().getName().equals(b.getActorRef().getName())) return true; } return false; } private BindingEndPoint getEndpoint(StructureClass sc, String name) { int pos = name.indexOf(EP_SEP); if (pos<0) return null; String portName = name.substring(0, pos); String refName = name.substring(pos+1, name.length()); ActorContainerRef ar = null; if (!refName.equals(LOCAL)) ar = getActorContainerRef(sc, refName); if (ar!=null) { if (ar instanceof ActorRef) sc = ((ActorRef) ar).getType(); else if (ar instanceof SubSystemRef) sc = ((SubSystemRef) ar).getType(); } Port port = getPort(sc, portName); BindingEndPoint ep = RoomFactory.eINSTANCE.createBindingEndPoint(); ep.setPort(port); ep.setActorRef(ar); return ep; } private EObject getLayerConnection(RoomClass rc, String name) { int pos = name.indexOf(CONN_SEP); if (pos<0) return null; if (rc instanceof StructureClass) { String saptname = name.substring(0, pos); String spptname = name.substring(pos+1, name.length()); StructureClass sc = (StructureClass) rc; SAPoint sapt = getSAPoint(sc, saptname); SPPoint sppt = getSPPoint(sc, spptname); for (LayerConnection bi : sc.getConnections()) { if (isSAPoint(bi.getFrom(),sapt) && isSPPoint(bi.getTo(),sppt)) return bi; } } return null; } private SPPoint getSPPoint(StructureClass sc, String name) { int pos = name.indexOf(EP_SEP); if (pos<0) return null; String refName = name.substring(0, pos); String sppName = name.substring(pos+1, name.length()); if (sc instanceof ActorContainerClass) { for (ActorRef ar : ((ActorContainerClass) sc).getActorRefs()) { if (ar.getName().equals(refName)) { for (SPPRef spp : ar.getType().getIfSPPs()) if (spp.getName().equals(sppName)) { SPPoint sppt = RoomFactory.eINSTANCE.createSPPoint(); sppt.setRef(ar); sppt.setService(spp); return sppt; } } } } else if (sc instanceof LogicalSystem) { for (SubSystemRef ssr : ((LogicalSystem) sc).getSubSystems()) { if (ssr.getName().equals(refName)) { for (SPPRef spp: ssr.getType().getIfSPPs()) if (spp.getName().equals(sppName)) { SPPoint sppt = RoomFactory.eINSTANCE.createSPPoint(); sppt.setRef(ssr); sppt.setService(spp); return sppt; } } } } return null; } private SAPoint getSAPoint(StructureClass sc, String name) { SAPoint sapt = getRelaySAPoint(sc, name); if (sapt!=null) return sapt; return getRefSAPoint(sc, name); } private SAPoint getRefSAPoint(StructureClass sc, String name) { if (sc instanceof ActorContainerClass) { for (ActorRef ar : ((ActorContainerClass)sc).getActorRefs()) { if (ar.getName().equals(name)) { RefSAPoint sapt = RoomFactory.eINSTANCE.createRefSAPoint(); sapt.setRef(ar); return sapt; } } } if (sc instanceof LogicalSystem) { for (SubSystemRef ssr : ((LogicalSystem) sc).getSubSystems()) { if (ssr.getName().equals(name)) { RefSAPoint sapt = RoomFactory.eINSTANCE.createRefSAPoint(); sapt.setRef(ssr); return sapt; } } } return null; } private SAPoint getRelaySAPoint(StructureClass sc, String name) { if (sc instanceof ActorContainerClass) { for (SPPRef spp : ((ActorContainerClass) sc).getIfSPPs()) { if (spp.getName().equals(name)) { RelaySAPoint sapt = RoomFactory.eINSTANCE.createRelaySAPoint(); sapt.setRelay(spp); return sapt; } } } return null; } private boolean isSAPoint(SAPoint a, SAPoint b) { if (a instanceof RefSAPoint && b instanceof RefSAPoint) { return ((RefSAPoint)a).getRef().getName().equals(((RefSAPoint)b).getRef().getName()); } else if (a instanceof RelaySAPoint && b instanceof RelaySAPoint) { return ((RelaySAPoint)a).getRelay().getName().equals(((RelaySAPoint)b).getRelay().getName()); } return false; } private boolean isSPPoint(SPPoint a, SPPoint b) { if (!a.getRef().getName().equals(b.getRef().getName())) return false; if (!a.getService().getName().equals(b.getService().getName())) return false; return true; } private ActorContainerRef getActorContainerRef(RoomClass rc, String name) { if (rc instanceof ActorContainerClass) { for (ActorRef ar : ((ActorContainerClass) rc).getActorRefs()) { if (ar.getName().equals(name)) return ar; } if (rc instanceof ActorClass) if (((ActorClass) rc).getBase()!=null) return getActorContainerRef(((ActorClass) rc).getBase(), name); } else if (rc instanceof LogicalSystem) { for (SubSystemRef ssr : ((LogicalSystem) rc).getSubSystems()) { if (ssr.getName().equals(name)) return ssr; } } return null; } protected Port getPort(RoomClass rc, String name) { if (rc instanceof ActorClass) { for (Port p : ((ActorClass) rc).getIfPorts()) { if (p.getName().equals(name)) return p; } for (Port p : ((ActorClass) rc).getIntPorts()) { if (p.getName().equals(name)) return p; } if (((ActorClass) rc).getBase()!=null) return getPort(((ActorClass) rc).getBase(), name); } else if (rc instanceof SubSystemClass) { for (Port p : ((SubSystemClass) rc).getRelayPorts()) { if (p.getName().equals(name)) return p; } } return null; } protected SPPRef getSPP(RoomClass rc, String name) { if (rc instanceof ActorContainerClass) { for (SPPRef spp : ((ActorContainerClass) rc).getIfSPPs()) { if (spp.getName().equals(name)) return spp; } if (rc instanceof ActorClass) if (((ActorClass)rc).getBase()!=null) return getSPP(((ActorClass)rc).getBase(), name); } return null; } private RoomClass getRoomClass(RoomModel model, String className) { for (DataClass dc : model.getDataClasses()) { if (dc.getName().equals(className)) return dc; } for (ProtocolClass pc : model.getProtocolClasses()) { if (pc.getName().equals(className)) return pc; } for (ActorClass ac : model.getActorClasses()) { if (ac.getName().equals(className)) return ac; } for (SubSystemClass ssc : model.getSubSystemClasses()) { if (ssc.getName().equals(className)) return ssc; } for (LogicalSystem ls : model.getSystems()) { if (ls.getName().equals(className)) return ls; } return null; } }