// sg.beh -- behavior for creating strategy graphs // $Id: sg.beh,v 1.16 2003/01/30 02:26:04 dougo Exp $ Strategy { /** Read a strategy expression from a byte stream. */ public static Strategy readFrom(InputStream in) throws ParseException {{ return readFrom(in, new HashMap()); }} /** Read a strategy expression from a char stream. */ public static Strategy readFrom(Reader in) throws ParseException {{ return readFrom(in, new HashMap()); }} /** Convert a string to a strategy. */ public static Strategy fromString(String s) {{ return fromString(s, new HashMap()); }} /** * Read a strategy expression from a byte stream. * Strategy references are resolved by looking them up in the * provided environent. */ public static Strategy readFrom(InputStream in, Map env) throws ParseException {{ Strategy s = StrategyExpression.parse(in).get_strategy(); s.attachEnv(env); return s; }} /** * Read a strategy expression from a char stream. * Strategy references are resolved by looking them up in the * provided environent. */ public static Strategy readFrom(Reader in, Map env) throws ParseException {{ Strategy s = StrategyExpression.parse(in).get_strategy(); s.attachEnv(env); return s; }} /** * Convert a string to a strategy. * Strategy references are resolved by looking them up in the * provided environent. */ public static Strategy fromString(String in, Map env) {{ Strategy s = StrategyExpression.parse(in).get_strategy(); s.attachEnv(env); return s; }} } Strategy { void attachEnv(Map env) to StrategyReference { before StrategyReference {{ host.env = env; }} } } StrategyGraph { {{ List edgeList = new ArrayList(); class IncidentEdges { List incoming = new ArrayList(), outgoing = new ArrayList(); } Map nodes = new HashMap(); // node -> IncidentEdges Set sources = new HashSet(), targets = new HashSet(); SymbolicNameMapI nameMap = null; }} init {{ edges = new SGEdge_SList(); }} StrategyGraph toGraph() {{ if (edgeList.isEmpty()) { Enumeration e = edges.elements(); int i = 0; Set allSources = new HashSet(), allTargets = new HashSet(); while (e.hasMoreElements()) { SGEdge edge = (SGEdge) e.nextElement(); addEdge(edge, i++); allSources.add(edge.get_source()); allTargets.add(edge.get_target()); } if (sources.isEmpty()) sources = allSources; if (targets.isEmpty()) targets = allTargets; if (nameMap == null) nameMap = (parsedNameMap == null ? new NameMap() : parsedNameMap); parsedNameMap = null; } return this; }} /* Add an edge to the strategy graph. */ public void addEdge(SGEdge edge) {{ addEdge(edge, edges.size()); edges.addElement(edge); }} void addEdge(SGEdge edge, int i) {{ edgeList.add(edge); GlobSpec source = edge.get_source(); if (edge.isSource()) sources.add(source); IncidentEdges ie = (IncidentEdges) nodes.get(source); if (ie == null) nodes.put(source, ie = new IncidentEdges()); ie.outgoing.add(new Integer(i)); GlobSpec target = edge.get_target(); if (edge.isTarget()) targets.add(target); ie = (IncidentEdges) nodes.get(target); if (ie == null) nodes.put(target, ie = new IncidentEdges()); ie.incoming.add(new Integer(i)); }} } PathDirective { {{ StrategyGraph graph; }} public StrategyGraph getGraph() {{ if (graph == null) graph = toGraph(); return graph; }} } PathDirective { StrategyGraph toGraph() to { From, NegativeConstraint, PositiveConstraint, To, ToStop, NameMap } { {{ SGEdge edge; }} {{ NameMap map = new NameMap(); }} before PathDirective {{ return_val = new StrategyGraph(); return_val.nameMap = map; }} before From {{ ClassGlobSpec sourcespec = host.get_sources(); edge = new SGEdge(); edge.set_source(sourcespec.toGlobSpec()); edge.set_sourcemarker(new SourceMarker()); }} before NegativeConstraint {{ edge.set_constraint(host); }} before PositiveConstraint {{ GlobSpec glob = host.get_glob(); edge.set_target(glob); return_val.addEdge(edge); edge = new SGEdge(); edge.set_source(glob); }} before ToStop {{ // Bypass the target(s). Bypassing constraint = Bypassing.parse("bypassing " + host.get_targets()); edge.set_constraint(constraint.intersectWith(edge.get_constraint())); }} after TargetDirective {{ ClassGlobSpec targets = host.get_targets(); edge.set_target(targets.toGlobSpec()); edge.set_targetmarker(new TargetMarker()); return_val.addEdge(edge); }} before NameMap {{ return_val.nameMap = NameMap.compose(host, map); }} } } Bypassing { NegativeConstraint intersectWith(NegativeConstraint constraint) {{ if (constraint == null) return this; if (constraint instanceof OnlyThrough) return constraint; return new Bypassing(glob.union(constraint.get_glob())); }} } Main { /** Testing stub. */ public static void main(String args[]) {{ edu.neu.ccs.demeter.dj.ClassGraph cg = new edu.neu.ccs.demeter.dj.ClassGraph( true,false); // "edu.neu.ccs.demeter.aplib.mysg",true,false); BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); try { XAspectLanguage2 s = XAspectLanguage2.parse(in); List snl = cg.gather(s, "from XAspectLanguage2 to StrategyName"); System.out.println(snl.size() + " " + s); } catch (ParseException e) { System.err.println(e.getMessage()); } }} }