001: /*
002: * Copyright 2007 Bastian Schenke Licensed under the Apache License, Version 2.0 (the "License");
003: * you may not use this file except in compliance with the License.
004: * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
005: * Unless required by applicable law or agreed to in writing, software distributed under the
006: * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
007: * either express or implied. See the License for the specific language governing permissions
008: * and limitations under the License.
009: */
010: package nz.org.take.r2ml;
011:
012: import java.util.ArrayList;
013: import java.util.Collection;
014: import java.util.HashMap;
015: import java.util.Map;
016: import java.util.Stack;
017:
018: import javax.xml.namespace.QName;
019:
020: import nz.org.take.Predicate;
021: import nz.org.take.SimplePredicate;
022: import nz.org.take.Variable;
023:
024: /**
025: * @author Bastian Schenke (bastian.schenke@googlemail.com)
026: *
027: */
028: public class MappingContext {
029:
030: private static MappingContext singletonContext = null;
031:
032: private Map<QName, Variable> variables = new HashMap<QName, Variable>();
033:
034: private Map<QName, Predicate> predicates = new HashMap<QName, Predicate>();
035:
036: private Stack<XmlTypeHandler> ancestors = new Stack<XmlTypeHandler>();
037: private Stack<String> ruleIDs = new Stack<String>();
038:
039: private boolean insideCondition = false;
040:
041: private Collection<String> propertyPredicateNames = new ArrayList<String>();
042:
043: /**
044: * Return the singleton instance of this MappingContext.
045: *
046: * @return the Singleton - MappingContext
047: */
048: public static MappingContext get() {
049: if (singletonContext == null) {
050: singletonContext = new MappingContext();
051: }
052: return singletonContext;
053: }
054:
055: /**
056: * This method is only for debugging and test purposes.
057: *
058: * @return
059: */
060: public boolean isClean() {
061: return (ancestors.size() == 0);
062: }
063:
064: public static void reset() {
065: singletonContext = null;
066: }
067:
068: /**
069: * @param string
070: * @param variable
071: */
072: void addVariable(String name, Variable variable) {
073: addVariable(new QName("", name), variable);
074: }
075:
076: void addVariable(QName name, Variable variable) {
077: variables.put(name, variable);
078: }
079:
080: /**
081: * @param localName
082: * @return the variable
083: */
084: Variable getVariable(String localName) {
085: return getVariable(new QName("", localName));
086: }
087:
088: /**
089: * @param fullName a fully qualified xml name
090: * @return the variable
091: */
092: Variable getVariable(QName fullName) {
093: return variables.get(fullName);
094: }
095:
096: /**
097: * @param predicate a new predicate
098: */
099: void addPredicate(Predicate predicate) {
100: addPredicate(new QName("", predicate.getName()), predicate);
101: }
102:
103: void addPredicate(QName fullName, Predicate predicate) {
104: predicates.put(fullName, predicate);
105: }
106:
107: public Predicate getPredicate(String localName) {
108: return getPredicate(new QName("", localName));
109: }
110:
111: public Predicate getPredicate(QName fullName) {
112: Predicate predicate = predicates.get(fullName);
113: if (predicate == null)
114: return null;
115: if (isConclusion() && !(predicate instanceof SimplePredicate))
116: return null;
117: return predicate;
118: }
119:
120: /**
121: * Each handler that may effect the way children are processed has to
122: * register. The policy is to unregister again after calling all children
123: * handler.
124: *
125: * @param handler
126: * the visiting handler
127: * @see void leave(XmlTypeHandler handler)
128: */
129: void enter(XmlTypeHandler handler) {
130: if (handler instanceof ConditionHandler) {
131: this .insideCondition = true;
132: }
133:
134: ancestors.push(handler);
135: }
136:
137: void enter(XmlTypeHandler handler, String ruleId) {
138: if (handler instanceof ConditionHandler) {
139: this .insideCondition = true;
140: }
141: ruleIDs.push(ruleId);
142: ancestors.push(handler);
143: }
144:
145: /**
146: * Each handler that registers itself in the context has to unregister again
147: * after he finished the processing of its children.
148: *
149: * @param handler
150: * the leaving handler
151: * @throws R2MLException
152: * if the handler is not the same as the one on top of the stack
153: * (recursion not properly resolved)
154: */
155: void leave(XmlTypeHandler handler) throws R2MLException {
156: XmlTypeHandler current = ancestors.pop();
157: if (!current.equals(handler)) {
158: R2MLDriver.get().logger
159: .debug("Recursion error! Last handler entering handler was \""
160: + current.getClass().getSimpleName()
161: + "\" actual leaving handler is \""
162: + handler.getClass().getSimpleName()
163: + "\"!");
164: throw new R2MLException("Error while resolving recursion."
165: + "Last handler entering handler was \""
166: + current.getClass().getSimpleName()
167: + "\" actual leaving handler is \""
168: + handler.getClass().getSimpleName() + "\"!");
169: }
170: if (handler instanceof ConditionHandler) {
171: insideCondition = false;
172: }
173:
174: }
175:
176: void leave(XmlTypeHandler handler, String ruleId)
177: throws R2MLException {
178: XmlTypeHandler current = ancestors.pop();
179: String currentRuleId = ruleIDs.pop();
180: if (!current.equals(handler)) {
181: R2MLDriver.get().logger
182: .debug("Recursion error! Last handler entering handler was \""
183: + current.getClass().getSimpleName()
184: + "\" actual leavung handler is \""
185: + handler.getClass().getSimpleName()
186: + "\"!");
187: throw new R2MLException("Error while resolving recursion."
188: + "Last handler entering handler was \""
189: + current.getClass().getSimpleName()
190: + "\" actual leaving handler is \""
191: + handler.getClass().getSimpleName() + "\"!");
192: }
193: if (handler instanceof ConditionHandler) {
194: insideCondition = false;
195: }
196:
197: }
198:
199: public boolean isInsideCondition() {
200: return insideCondition;
201: }
202:
203: public boolean isCondition() {
204: return ancestors.peek() instanceof ConditionHandler;
205: }
206:
207: public boolean isConclusion() {
208: return ancestors.peek() instanceof ConclusionHandler;
209: }
210:
211: public void cleanUpToHandler(XmlTypeHandler handler)
212: throws R2MLException {
213: while (!ancestors.peek().equals(handler)) {
214: leave(ancestors.peek());
215: }
216: leave(handler);
217: }
218:
219: public Collection<String> getPropertyPredicateNames() {
220: return propertyPredicateNames;
221: }
222:
223: void addPredicatePropertyName(String name) {
224: propertyPredicateNames.add(name);
225: }
226:
227: }
|