001: //THIS SOFTWARE IS PROVIDED BY SOFTARIS PTY.LTD. AND OTHER METABOSS
002: //CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
003: //BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
004: //FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SOFTARIS PTY.LTD.
005: //OR OTHER METABOSS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
006: //INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
007: //LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
008: //OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
009: //LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
010: //NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
011: //EVEN IF SOFTARIS PTY.LTD. OR OTHER METABOSS CONTRIBUTORS ARE ADVISED OF THE
012: //POSSIBILITY OF SUCH DAMAGE.
013: //
014: //Copyright 2000-2005 © Softaris Pty.Ltd. All Rights Reserved.
015: package tudresden.ocl;
016:
017: import java.io.IOException;
018: import java.io.PushbackReader;
019: import java.io.StringReader;
020:
021: import tudresden.ocl.check.QueryableFactory;
022: import tudresden.ocl.check.types.DefaultTypeFactory;
023: import tudresden.ocl.check.types.ModelFacade;
024: import tudresden.ocl.check.types.Type;
025: import tudresden.ocl.parser.OclParser;
026: import tudresden.ocl.parser.OclParserException;
027: import tudresden.ocl.parser.lexer.Lexer;
028: import tudresden.ocl.parser.node.Start;
029:
030: /** This class is the wrapper around an OclTree class used to override some unwanted behaviour.
031: * The problems we are trying to solve here are:
032: * <UL>
033: * <LI>The get() method in the DefaultTypeFactory class has a problem where all expressions with names
034: * starting with reserved name for collection operations will be assumed to be collections. Fore example the
035: * 'SettlementDate' field will be mistakenly recognised as Set(xxxx) definition.</LI>
036: * </UL> */
037: public class MetaBossOclTree extends OclTree {
038: private static class SpecialTypeFactory extends DefaultTypeFactory {
039: public SpecialTypeFactory(ModelFacade mf) {
040: super (mf);
041: }
042:
043: public Type get(String name) {
044: // check for collection types
045: // Fixing a problem with the default implementation
046: // the problem is that no check is being made if braces exist
047: if (name.startsWith("Collection") == true
048: && name.equals("Collection") == false) {
049: int lOpeningParenthesis = name.indexOf('(');
050: int lClosingParenthesis = name.lastIndexOf(')');
051: if (lOpeningParenthesis > 0
052: && lClosingParenthesis > lOpeningParenthesis)
053: return getCollection(get(name.substring(
054: lOpeningParenthesis + 1,
055: lClosingParenthesis).trim()));
056: return myModelFacade.getClassifier(name);
057: } else if (name.startsWith("Sequence") == true
058: && name.equals("Sequence") == false) {
059: int lOpeningParenthesis = name.indexOf('(');
060: int lClosingParenthesis = name.lastIndexOf(')');
061: if (lOpeningParenthesis > 0
062: && lClosingParenthesis > lOpeningParenthesis)
063: return getSequence(get(name.substring(
064: lOpeningParenthesis + 1,
065: lClosingParenthesis).trim()));
066: return myModelFacade.getClassifier(name);
067: } else if (name.startsWith("Set") == true
068: && name.equals("Set") == false) {
069: int lOpeningParenthesis = name.indexOf('(');
070: int lClosingParenthesis = name.lastIndexOf(')');
071: if (lOpeningParenthesis > 0
072: && lClosingParenthesis > lOpeningParenthesis)
073: return getSet(get(name.substring(
074: lOpeningParenthesis + 1,
075: lClosingParenthesis).trim()));
076: return myModelFacade.getClassifier(name);
077: } else if (name.startsWith("Bag") == true
078: && name.equals("Bag") == false) {
079: int lOpeningParenthesis = name.indexOf('(');
080: int lClosingParenthesis = name.lastIndexOf(')');
081: if (lOpeningParenthesis > 0
082: && lClosingParenthesis > lOpeningParenthesis)
083: return getBag(get(name.substring(
084: lOpeningParenthesis + 1,
085: lClosingParenthesis).trim()));
086: return myModelFacade.getClassifier(name);
087: }
088: return super .get(name);
089: }
090: }
091:
092: // Overrien to profide custom type factory
093: public static OclTree createTree(String oclExpression,
094: ModelFacade mf)
095: throws tudresden.ocl.parser.OclParserException, IOException {
096: return createTree(oclExpression, mf, null);
097: }
098:
099: // Overrien to profide custom type factory
100: public static OclTree createTree(String oclExpression,
101: ModelFacade mf, QueryableFactory qf) throws IOException {
102: try {
103: OclTree tree = new OclTree();
104: if (qf != null)
105: tree.setQueryableFactory(qf);
106: tree.tFactory = new SpecialTypeFactory(mf); // Creating specialised implementation
107:
108: Lexer lexer = new Lexer(new PushbackReader(
109: new StringReader(oclExpression)));
110: OclParser p = new OclParser(lexer);
111: Start startNode = p.parse();
112: tree.ast = startNode;
113:
114: // find name of constraint
115: ConstraintNameFinder nameFinder = new ConstraintNameFinder();
116: startNode.apply(nameFinder);
117: tree.name = nameFinder.getName();
118: return tree;
119: } catch (tudresden.ocl.parser.parser.ParserException e) {
120: throw new OclParserException(e.getMessage());
121: } catch (tudresden.ocl.parser.lexer.LexerException e) {
122: throw new OclParserException(e.getMessage());
123: }
124: }
125: }
|