001    package org.mesopotamia.lang.java;
002    
003    import java.util.HashMap;
004    import java.util.List;
005    import java.util.Map;
006    
007    import org.mesopotamia.MesopotamiaException;
008    import org.mesopotamia.NodeData;
009    import org.mesopotamia.RepositoryLanguage;
010    import org.mesopotamia.Scan;
011    import org.mesopotamia.lang.java.ref.MethodInfo;
012    import org.mesopotamia.lang.java.ref.Scope;
013    import org.mesopotamia.lang.java.ref.TypeInfo;
014    import org.mesopotamia.lang.java.ref.VariableInfo;
015    import org.w3c.dom.Element;
016    
017    import biz.hammurapi.util.CollectionVisitable;
018    import biz.hammurapi.util.Visitor;
019    
020    public class CompoundStatement extends JavaLanguageElement implements Statement, Scope {
021    
022            public CompoundStatement(
023                            NodeData xData, 
024                            Class<?> context, 
025                            Scan scan,
026                            RepositoryLanguage language, 
027                            Object environment) throws MesopotamiaException {
028                    super(xData, context, scan, language, environment);
029    
030                    // Select attributes
031                    Statements = select(Statement.class, "*");
032    
033            }
034    
035            public void toDom(Element holder) {
036                    super.toDom(holder);
037    
038                    // Serialize attributes
039                    setElement(holder, "Statements", Statements);
040            }
041    
042            // Attributes
043            private List<Statement> Statements;
044    
045            // Accessors
046            public List<Statement> getStatements() {
047                    return Statements;
048            }
049    
050            protected void acceptChildren(Visitor visitor) {
051                    super.acceptChildren(visitor);
052                    // Visiting non-text attributes
053                    new CollectionVisitable(Statements, false).accept(visitor);
054            }
055            
056            private Scope enclosingScope;
057            private Map<String, VariableDefinition> variables;
058            private Map<String, TypeDefinition> types;
059            private boolean scopeSet;
060    
061            public MethodInfo findMethod(String name, String[] parameterTypes) {
062                    if (!scopeSet) {
063                            setScope();
064                    }
065                    
066                    return enclosingScope == null ? null : enclosingScope.findMethod(name, parameterTypes);
067            }
068    
069            private synchronized void setScope() {
070                    if (!scopeSet) {
071                            scopeSet = true;                        
072                    }
073                    variables = new HashMap<String, VariableDefinition>();
074                    types = new HashMap<String, TypeDefinition>();
075                    enclosingScope = findParent(Scope.class);
076                    
077                    for (Statement child: getStatements()) {
078                            if (child instanceof VariableDefinition) {
079                                    VariableDefinition vd = (VariableDefinition) child;
080                                    variables.put(vd.getName(), vd);
081                            } else if (child instanceof TypeDefinition) {
082                                    TypeDefinition td = (TypeDefinition) child;
083                                    types.put(td.getName(), td);
084                            }
085                    }
086            }
087    
088            public TypeInfo findType(String name) {
089                    if (!scopeSet) {
090                            setScope();
091                    }
092                    
093                    TypeDefinition ret = types.get(name);
094                    if (ret!=null) {
095                            return ret;
096                    }
097                    
098                    return enclosingScope == null ? null : enclosingScope.findType(name);
099            }
100    
101            public VariableInfo findVariable(String name) {
102                    if (!scopeSet) {
103                            setScope();
104                    }
105                    
106                    VariableDefinition vd = variables.get(name);
107                    if (vd!=null) {
108                            return vd;
109                    }
110                    
111                    return enclosingScope == null ? null : enclosingScope.findVariable(name);
112            }
113    
114    }