/* * Copyright 2008 Google Inc. * * 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 com.google.template.soy.soytree; import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.base.Predicate; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.template.soy.base.SourceLocation; import com.google.template.soy.base.internal.SoyFileKind; import com.google.template.soy.basetree.CopyState; import com.google.template.soy.soytree.SoyNode.SplitLevelTopNode; import java.util.Map; import javax.annotation.Nullable; /** * Node representing a Soy file. * * <p>Important: Do not use outside of Soy code (treat as superpackage-private). * */ public final class SoyFileNode extends AbstractParentSoyNode<TemplateNode> implements SplitLevelTopNode<TemplateNode> { public static final Predicate<SoyFileNode> MATCH_SRC_FILENODE = new Predicate<SoyFileNode>() { @Override public boolean apply(@Nullable SoyFileNode input) { return input != null && input.getSoyFileKind() == SoyFileKind.SRC; } }; /** The kind of this Soy file */ private final SoyFileKind soyFileKind; /** The name of the containing delegate package, or null if none. */ @Nullable private final String delPackageName; /** This Soy file's namespace, or null if syntax version V1. */ private final NamespaceDeclaration namespaceDeclaration; /** Map from aliases to namespaces for this file. */ private final ImmutableMap<String, String> aliasToNamespaceMap; private final ImmutableList<AliasDeclaration> aliasDeclarations; private final String filePath; private final String fileName; /** * @param id The id for this node. * @param filePath The path to the Soy source file. * @param soyFileKind The kind of this Soy file. * @param namespaceDeclaration This Soy file's namespace and attributes. Nullable for backwards * compatibility only. * @param headerInfo Other file metadata, (e.g. delpackages, aliases) */ public SoyFileNode( int id, String filePath, SoyFileKind soyFileKind, NamespaceDeclaration namespaceDeclaration, TemplateNode.SoyFileHeaderInfo headerInfo) { super(id, null /* there is no source location. */); this.filePath = checkNotNull(filePath); this.fileName = SourceLocation.fileNameFromPath(filePath); this.soyFileKind = soyFileKind; this.delPackageName = headerInfo.delPackageName; this.namespaceDeclaration = namespaceDeclaration; // Immutable this.aliasDeclarations = headerInfo.aliasDeclarations; // immutable this.aliasToNamespaceMap = headerInfo.aliasToNamespaceMap; // immutable } /** * Copy constructor. * * @param orig The node to copy. */ private SoyFileNode(SoyFileNode orig, CopyState copyState) { super(orig, copyState); this.soyFileKind = orig.soyFileKind; this.filePath = orig.filePath; this.fileName = orig.fileName; this.delPackageName = orig.delPackageName; this.namespaceDeclaration = orig.namespaceDeclaration; // Immutable this.aliasDeclarations = orig.aliasDeclarations; // immutable this.aliasToNamespaceMap = orig.aliasToNamespaceMap; // immutable } @Override public Kind getKind() { return Kind.SOY_FILE_NODE; } /** Returns the kind of this Soy file. */ public SoyFileKind getSoyFileKind() { return soyFileKind; } /** Returns the name of the containing delegate package, or null if none. */ @Nullable public String getDelPackageName() { return delPackageName; } /** Returns this Soy file's namespace, or null if syntax version V1. */ @Nullable public String getNamespace() { return namespaceDeclaration.getNamespace(); } /** Returns the parsed namespace for the file. */ public NamespaceDeclaration getNamespaceDeclaration() { return namespaceDeclaration; } /** Returns the CSS namespaces required by this file (usable in any template in this file). */ public ImmutableList<String> getRequiredCssNamespaces() { return namespaceDeclaration.getRequiredCssNamespaces(); } /** Returns the CSS base namespace for this file (usable in any template in this file). */ @Nullable public String getCssBaseNamespace() { return namespaceDeclaration.getCssBaseNamespace(); } /** Returns the map from aliases to namespaces for this file. */ public ImmutableMap<String, String> getAliasToNamespaceMap() { return aliasToNamespaceMap; } /** Returns the syntactic alias directives in the file. For semantics, use aliasToNamespaceMap. */ public ImmutableList<AliasDeclaration> getAliasDeclarations() { return aliasDeclarations; } /** Returns the path to the source Soy file ("unknown" if not supplied). */ public String getFilePath() { return filePath; } /** Returns this Soy file's name. */ @Nullable public String getFileName() { return fileName; } /** @deprecated SoyFileNodes don't have source locations. */ @Deprecated @Override public SourceLocation getSourceLocation() { return super.getSourceLocation(); } @Override public String toSourceString() { StringBuilder sb = new StringBuilder(); if (delPackageName != null) { sb.append("{delpackage ").append(delPackageName).append("}\n"); } sb.append(namespaceDeclaration.toSourceString()); if (!aliasToNamespaceMap.isEmpty()) { sb.append("\n"); for (Map.Entry<String, String> entry : aliasToNamespaceMap.entrySet()) { String alias = entry.getKey(); String aliasNamespace = entry.getValue(); if (aliasNamespace.equals(alias) || aliasNamespace.endsWith("." + alias)) { sb.append("{alias ").append(aliasNamespace).append("}\n"); } else { sb.append("{alias ").append(aliasNamespace).append(" as ").append(alias).append("}\n"); } } } for (SoyNode child : getChildren()) { sb.append("\n"); sb.append(child.toSourceString()); } return sb.toString(); } @Override public SoyFileSetNode getParent() { return (SoyFileSetNode) super.getParent(); } @Override public SoyFileNode copy(CopyState copyState) { return new SoyFileNode(this, copyState); } }