/* * Copyright 2003-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jetbrains.mps.smodel.runtime.impl; import jetbrains.mps.smodel.adapter.ids.SConceptId; import jetbrains.mps.smodel.adapter.ids.SContainmentLinkId; import jetbrains.mps.smodel.adapter.ids.SPropertyId; import jetbrains.mps.smodel.adapter.ids.SReferenceLinkId; import jetbrains.mps.smodel.runtime.BaseLinkDescriptor; import jetbrains.mps.smodel.runtime.BasePropertyDescriptor; import jetbrains.mps.smodel.runtime.BaseReferenceDescriptor; import jetbrains.mps.smodel.runtime.ConceptDescriptor; import jetbrains.mps.smodel.runtime.LinkDescriptor; import jetbrains.mps.smodel.runtime.PropertyDescriptor; import jetbrains.mps.smodel.runtime.ReferenceDescriptor; import jetbrains.mps.smodel.runtime.StaticScope; import org.jetbrains.annotations.NotNull; import org.jetbrains.mps.openapi.model.SNodeReference; import java.util.ArrayList; import java.util.List; /** * evgeny, 4/24/13 */ public class ConceptDescriptorBuilder { private static final String[] EMPTY_STRINGS = new String[0]; private static final SConceptId[] EMPTY_IDS = new SConceptId[0]; private final String conceptFqName; private SConceptId id; private String superConcept; private boolean isInterfaceConcept; private boolean isAbstract; private boolean isFinal; private boolean isRootable; //meaningless for interfaces private String conceptAlias; private String shortDescription; private String helpUrl; private StaticScope staticScope; private SConceptId superConceptId; private SConceptId[] parentIds; private SNodeReference sourceNodeRef; private List<PropertyDescriptor> ownProperties = new ArrayList<PropertyDescriptor>(); private List<ReferenceDescriptor> ownReferences = new ArrayList<ReferenceDescriptor>(); private List<LinkDescriptor> ownLinks = new ArrayList<LinkDescriptor>(); private int version = 0; //version 1 means canBeRoot is set //remove after migration public ConceptDescriptorBuilder(String conceptFqName) { this.conceptFqName = conceptFqName; } public ConceptDescriptorBuilder(String conceptFqName, SConceptId id) { this.conceptFqName = conceptFqName; this.id = id; } public ConceptDescriptorBuilder version(int version) { this.version = version; return this; } public ConceptDescriptorBuilder super_(@NotNull String qualifiedName) { superConcept = qualifiedName; return this; } public ConceptDescriptorBuilder super_(@NotNull SConceptId id) { superConceptId = id; return this; } public ConceptDescriptorBuilder parents(String... parents) { // intentionally no-op return this; } public ConceptDescriptorBuilder parentIds(SConceptId... parents) { this.parentIds = parents; return this; } public ConceptDescriptorBuilder properties(String... names) { // intentional no-op return this; } public ConceptDescriptorBuilder propertyDescriptors(Prop... d) { for (Prop p : d) { ownProperties.add(new BasePropertyDescriptor(new SPropertyId(id, p.myId), p.myName, p.mySrcNode)); } return this; } public ConceptDescriptorBuilder references(String... names) { // intentional no-op return this; } public ConceptDescriptorBuilder referenceDescriptors(Ref... d) { for (Ref r : d) { ownReferences.add(new BaseReferenceDescriptor(new SReferenceLinkId(id, r.myId), r.myName, r.myTargetConcept, r.myIsOptional, r.mySrcNode)); } return this; } public ConceptDescriptorBuilder children(@NotNull String[] names, @NotNull boolean[] multiple) { // intentional no-op return this; } public ConceptDescriptorBuilder childDescriptors(Link... d) { for (Link l : d) { ownLinks.add(new BaseLinkDescriptor(new SContainmentLinkId(id, l.myId), l.myName, l.myTargetConcept, l.myIsOptional, l.myIsMultiple, l.myIsUnordered, l.mySrcNode)); } return this; } public ConceptDescriptorBuilder unordered(String... names) { // intentional no-op return this; } public ConceptDescriptorBuilder abstract_() { isAbstract = true; return this; } public ConceptDescriptorBuilder final_() { isFinal = true; return this; } public ConceptDescriptorBuilder rootable() { isRootable = true; return this; } public ConceptDescriptorBuilder interface_() { isInterfaceConcept = true; return this; } public ConceptDescriptorBuilder alias(@NotNull String alias, String shortDescription) { this.conceptAlias = alias; this.shortDescription = shortDescription; return this; } public ConceptDescriptorBuilder helpURL(String value) { helpUrl = value; return this; } public ConceptDescriptorBuilder staticScope(StaticScope value) { this.staticScope = value; return this; } public ConceptDescriptorBuilder sourceNode(SNodeReference value) { this.sourceNodeRef = value; return this; } public ConceptDescriptor create() { return new CompiledConceptDescriptor( version, id, conceptFqName, superConceptId, superConcept, isInterfaceConcept, parentIds == null ? EMPTY_IDS : parentIds, null, ownProperties.toArray(new PropertyDescriptor[ownProperties.size()]), ownReferences.toArray(new ReferenceDescriptor[ownReferences.size()]), ownLinks.toArray(new LinkDescriptor[ownLinks.size()]), isAbstract || isInterfaceConcept, isFinal, isRootable, conceptAlias == null ? "" : conceptAlias, shortDescription == null ? "" : shortDescription, helpUrl == null ? "" : helpUrl, staticScope == null ? StaticScope.GLOBAL : staticScope, sourceNodeRef); } public static class Link { final long myId; final String myName; final SConceptId myTargetConcept; final boolean myIsOptional; final boolean myIsMultiple; final boolean myIsUnordered; final SNodeReference mySrcNode; public Link(long id, String name, SConceptId targetConcept, boolean isOptional, boolean isMultiple, boolean isUnordered) { this(id, name, targetConcept, isOptional, isMultiple, isUnordered, null); } public Link(long id, String name, SConceptId targetConcept, boolean isOptional, boolean isMultiple, boolean isUnordered, SNodeReference srcNode) { myId = id; myName = name; myTargetConcept = targetConcept; myIsOptional = isOptional; myIsMultiple = isMultiple; myIsUnordered = isUnordered; mySrcNode = srcNode; } } public static class Prop { final long myId; final String myName; final SNodeReference mySrcNode; public Prop(long id, String name) { this(id, name, null); } public Prop(long id, String name, SNodeReference srcNode) { myId = id; myName = name; mySrcNode = srcNode; } } public static class Ref { final long myId; final String myName; final SConceptId myTargetConcept; final boolean myIsOptional; final SNodeReference mySrcNode; public Ref(long id, String name, SConceptId targetConcept, boolean isOptional) { this(id, name, targetConcept, isOptional, null); } public Ref(long id, String name, SConceptId targetConcept, boolean isOptional, SNodeReference srcNode) { myId = id; myName = name; myTargetConcept = targetConcept; myIsOptional = isOptional; mySrcNode = srcNode; } } }