com.google.common.css.compiler.ast.CssValueNode.java Source code

Java tutorial

Introduction

Here is the source code for com.google.common.css.compiler.ast.CssValueNode.java

Source

/*
 * 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.common.css.compiler.ast;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.UnmodifiableIterator;
import com.google.common.css.SourceCodeLocation;

import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import javax.annotation.Nullable;

/**
 * A CSS node that holds a value of some sort. This is the base class for all
 * the nodes in the abstract syntax tree that have a value.
 *
 * TODO(oana): Maybe de-emphasize the value aspect, allow value to be null, and
 * rename this as CssTermNode.
 *
 */
public abstract class CssValueNode extends CssNode {

    /** The value contained by the node. */
    private String value;

    /** Annotation to show whether this is a default value or not. */
    private boolean isDefault;

    /**
     * Constructor of a node that contains a value.
     *
     * @param value
     * @param sourceCodeLocation
     */
    public CssValueNode(@Nullable String value, @Nullable SourceCodeLocation sourceCodeLocation) {
        super(sourceCodeLocation);
        this.value = value;
        this.isDefault = false;
    }

    /**
     * Constructor of a node that contains a value.
     *
     * @param value
     */
    public CssValueNode(String value) {
        this(value, null);
    }

    /**
     * Copy constructor.
     *
     * @param node
     */
    public CssValueNode(CssValueNode node) {
        this(node.getValue(), node.getSourceCodeLocation());
        this.isDefault = node.getIsDefault();
    }

    @Override
    public abstract CssValueNode deepCopy();

    public String getValue() {
        return this.value;
    }

    /**
     * Subclasses should perform additional consistency checks. For example, a
     * boolean expression node will not allow setting this as boolean expression
     * trees are immutable.
     */
    public void setValue(String value) {
        Preconditions.checkNotNull(value);
        this.value = value;
    }

    public void setIsDefault(boolean isDefault) {
        this.isDefault = isDefault;
    }

    public boolean getIsDefault() {
        return isDefault;
    }

    /**
     * Visit just the leaves in the subtrees from the given roots.
     */
    public static Iterable<CssValueNode> leaves(final Collection<CssValueNode> roots) {
        return new Iterable<CssValueNode>() {
            public Iterator<CssValueNode> iterator() {
                return new UnmodifiableIterator<CssValueNode>() {
                    LinkedList<CssValueNode> q;
                    {
                        q = Lists.newLinkedList();
                        q.addAll(roots);
                    }

                    List<CssValueNode> expand(CssValueNode n) {
                        if (n instanceof CssBooleanExpressionNode) {
                            CssBooleanExpressionNode b = (CssBooleanExpressionNode) n;
                            return ImmutableList.<CssValueNode>of(b.getLeft(), b.getRight());
                        } else if (n instanceof CssCompositeValueNode) {
                            CssCompositeValueNode c = (CssCompositeValueNode) n;
                            return c.getValues();
                        } else {
                            return ImmutableList.<CssValueNode>of(n);
                        }
                    }

                    void advance() {
                        CssValueNode unexpanded;
                        List<CssValueNode> expanded;
                        do {
                            unexpanded = q.remove();
                            expanded = expand(unexpanded);
                            q.addAll(0, expanded);
                        } while (expanded.size() != 1 || !expanded.get(0).equals(unexpanded));
                    }

                    @Override
                    public boolean hasNext() {
                        return !q.isEmpty();
                    }

                    @Override
                    public CssValueNode next() {
                        advance();
                        return q.remove();
                    }
                };
            }
        };
    }

    /**
     * Use for debugging only.
     */
    @Override
    public String toString() {
        return getValue();
    }
}