/* * 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.generator.impl.dependencies; import org.jdom.Attribute; import org.jdom.Element; import org.jetbrains.mps.openapi.model.SModel; import org.jetbrains.mps.openapi.model.SModelReference; import org.jetbrains.mps.openapi.model.SNode; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; /** * FIXME if we'd like to keep using this object, shall refactor all storage from string to native objects (e.g. SModelReference, SNodeId, etc) * Strings consume quite a lot of memory on startup * Evgeny Gryaznov, Jun 1, 2010 */ public class GenerationRootDependencies { private static final String ATTR_ID = "id"; private static final String ATTR_NAME = "name"; private static final String ATTR_HASH = "hash"; private static final String ATTR_DEPENDS_ON_CONDITIONALS = "dependsOnCreated"; private static final String ATTR_DEPENDS_ON_NODES = "dependsOnNodes"; private static final String NODE_DEPENDS_ON = "dep"; private static final String NODE_FILE = "file"; private static final String ATTR_ROOT_ID = "root"; private static final String ATTR_MODEL_ID = "model"; private static final String TRUE = "true"; private String myRootId; private String myRootName; private String myHash; private boolean myDependsOnConditionals; private boolean myDependsOnNodes; private List<String> myLocal; private List<String> myExternal; private List<String> myGeneratedFiles; public GenerationRootDependencies(String rootId, String rootName, String rootHash, boolean dependsOnConditionals, boolean dependsOnNodes, List<String> local, List<String> external, List<String> files) { this.myRootId = rootId; this.myRootName = rootName; this.myHash = rootHash; this.myDependsOnConditionals = dependsOnConditionals; this.myDependsOnNodes = dependsOnNodes; this.myLocal = local; this.myExternal = external; this.myGeneratedFiles = files; } public String getRootId() { return myRootId; } public String getRootName() { return myRootName; } public String getHash() { return myHash; } public boolean isDependsOnConditionals() { return myDependsOnConditionals; } public boolean isDependsOnNodes() { return myDependsOnNodes; } public List<String> getLocal() { return Collections.unmodifiableList(myLocal); } public List<String> getExternal() { return Collections.unmodifiableList(myExternal); } public List<String> getFiles() { return myGeneratedFiles == null ? Collections.<String>emptyList() : Collections.unmodifiableList(myGeneratedFiles); } public void addGeneratedFile(String name) { if (name == null) { throw new IllegalArgumentException("name is null"); } if (myGeneratedFiles == null) { myGeneratedFiles = new ArrayList<String>(2); } if (!myGeneratedFiles.contains(name)) { myGeneratedFiles.add(name); } } public void saveTo(Element element) { if (myRootId != null) { element.setAttribute(ATTR_ID, this.myRootId); } if (myRootName != null) { element.setAttribute(ATTR_NAME, this.myRootName); } if (myHash != null) { element.setAttribute(ATTR_HASH, this.myHash); } if (myDependsOnConditionals) { element.setAttribute(ATTR_DEPENDS_ON_CONDITIONALS, TRUE); } if (myDependsOnNodes) { element.setAttribute(ATTR_DEPENDS_ON_NODES, TRUE); } for (String id : myLocal) { Element node = new Element(NODE_DEPENDS_ON); node.setAttribute(ATTR_ROOT_ID, id); element.addContent(node); } for (String id : myExternal) { Element node = new Element(NODE_DEPENDS_ON); node.setAttribute(ATTR_MODEL_ID, id); element.addContent(node); } if (myGeneratedFiles != null) { Collections.sort(myGeneratedFiles); for (String file : myGeneratedFiles) { Element node = new Element(NODE_FILE); node.setAttribute(ATTR_NAME, file); element.addContent(node); } } } public static String getValue(Element e, String attrId) { Attribute attr = e.getAttribute(attrId); return attr == null ? null : attr.getValue(); } public static GenerationRootDependencies fromXml(Element element, boolean isCommon, Intern intern) { String rootId = isCommon ? null : intern.value(getValue(element, ATTR_ID)); String rootName = getValue(element, ATTR_NAME); String rootHash = getValue(element, ATTR_HASH); boolean dependsOnConditionals = "true".equals(getValue(element, ATTR_DEPENDS_ON_CONDITIONALS)); boolean dependsOnNodes = "true".equals(getValue(element, ATTR_DEPENDS_ON_NODES)); ArrayList<String> local = new ArrayList<String>(); ArrayList<String> external = new ArrayList<String>(); ArrayList<String> files = new ArrayList<String>(); for (Element e : element.getChildren(NODE_DEPENDS_ON)) { Attribute attr = e.getAttribute(ATTR_ROOT_ID); if (attr != null) { local.add(intern.value(attr.getValue())); } else if ((attr = e.getAttribute(ATTR_MODEL_ID)) != null) { external.add(intern.value(attr.getValue())); } } for (Element e : element.getChildren(NODE_FILE)) { String v = getValue(e, ATTR_NAME); if (v != null) { files.add(intern.value(v)); } } local.trimToSize(); external.trimToSize(); files.trimToSize(); return new GenerationRootDependencies(rootId, rootName, rootHash, dependsOnConditionals, dependsOnNodes, local, external, files); } public static GenerationRootDependencies fromData(RootDependenciesBuilder l) { final Collection<SNode> localNodes = l.getDependsOn(); final Collection<SModel> externalModels = l.getDependsOnModels(); List<String> local = new ArrayList<String>(localNodes.size()); for (SNode n : localNodes) { local.add(n.getNodeId().toString()); } Collections.sort(local); List<String> external = new ArrayList<String>(externalModels.size()); for (SModel m : externalModels) { final SModelReference modelRef = m.getReference(); external.add(modelRef.toString()); } Collections.sort(external); final SNode originalRoot = l.getOriginalRoot(); return new GenerationRootDependencies( originalRoot != null ? originalRoot.getNodeId().toString() : null, originalRoot != null ? originalRoot.getName() : null, l.getHash(), l.isDependsOnConditionals(), l.isDependsOnModelNodes(), local, external, null); } }