001package org.clafer.ast;
002
003import java.util.ArrayList;
004import java.util.Collections;
005import java.util.List;
006
007/**
008 * <p>
009 * The Clafer model. Also acts as the implicit "root" Clafer which nests above
010 * the top most Clafers.
011 * </p>
012 * <p>
013 * For example:
014 * <pre>
015 * abstract Feature
016 *     Cost -> integer
017 * Database : Feature
018 * </pre> Although the model is written syntactically like above, its
019 * representation internally is more like:
020 * <pre>
021 * #root#
022 *     abstract Feature
023 *         Cost -> integer
024 *     Database : Feature
025 * </pre> {@code #root#} is represented by this class.
026 * </p>
027 *
028 * @author jimmy
029 */
030public class AstModel extends AstConcreteClafer {
031
032    private final List<AstAbstractClafer> abstracts;
033
034    AstModel() {
035        super("#root#", new AstAbstractClafer("#clafer#", null));
036        super.withCard(new Card(1, 1));
037        this.abstracts = new ArrayList<>();
038        this.abstracts.add(claferClafer);
039        super.extending(claferClafer);
040    }
041
042    /**
043     * Returns the type every non-primitive type extends from.
044     *
045     * @return the Clafer named "clafer"
046     */
047    public AstAbstractClafer getTypeHierarchyRoot() {
048        return claferClafer;
049    }
050
051    /**
052     * Returns all the abstract Clafers
053     *
054     * @return all the abstract Clafers
055     */
056    public List<AstAbstractClafer> getAbstracts() {
057        return Collections.unmodifiableList(abstracts);
058    }
059
060    /**
061     * Add a new abstract Clafer to the model. .
062     *
063     * @param name the name of the abtract Clafer
064     * @return the new abstract Clafer
065     */
066    public AstAbstractClafer addAbstract(String name) {
067        AstAbstractClafer abstractClafer = new AstAbstractClafer(name, claferClafer).extending(claferClafer);
068        abstracts.add(abstractClafer);
069        return abstractClafer;
070    }
071
072    @Override
073    public AstModel extending(AstAbstractClafer superClafer) {
074        throw new UnsupportedOperationException("Cannot extend from " + getName());
075    }
076
077    @Override
078    public AstModel refTo(AstClafer targetType) {
079        throw new UnsupportedOperationException("Cannot ref from " + getName());
080    }
081
082    @Override
083    public AstModel refToUnique(AstClafer targetType) {
084        throw new UnsupportedOperationException("Cannot ref from " + getName());
085    }
086
087    @Override
088    public AstConcreteClafer withCard(Card card) {
089        throw new UnsupportedOperationException("Cannot set cardinality for " + getName());
090    }
091
092    @Override
093    public AstModel withGroupCard(Card groupCard) {
094        throw new UnsupportedOperationException("Cannot set group cardinality for " + getName());
095    }
096}