/* * Copyright (C) 2011 Laurent Caillette * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation, either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.novelang.common; import java.util.Set; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import org.apache.commons.lang.ClassUtils; import org.apache.commons.lang.NullArgumentException; import org.novelang.common.tree.ImmutableTree; import org.novelang.parser.NodeKind; /** * Specific immplementation of a {@link org.novelang.common.tree.Tree}. * * @author Laurent Caillette */ public class SimpleTree extends ImmutableTree< SyntacticTree > implements SyntacticTree { private final String text ; private final NodeKind nodekind ; private final Location location ; public SimpleTree( final String text, final SyntacticTree... children ) { this( text, null, Lists.newArrayList( children ) ) ; } public SimpleTree( final String text, final Location location, final SyntacticTree... children ) { this( text, location, Lists.newArrayList( children ) ) ; } public SimpleTree( final String text, final Iterable< ? extends SyntacticTree> children ) { this( text, null, children ) ; } public SimpleTree( final NodeKind nodeKind, final SyntacticTree... children ) { this( nodeKind, Lists.newArrayList( children ) ) ; } public SimpleTree( final NodeKind nodeKind, final Location location, final SyntacticTree... children ) { this( nodeKind, location, Lists.newArrayList( children ) ) ; } public SimpleTree( final String text, final Location location, final Iterable< ? extends SyntacticTree > children ) { super( children ) ; this.location = location ; this.text = text ; this.nodekind = null ; } public SimpleTree( final NodeKind nodeKind, final Location location, final Iterable< ? extends SyntacticTree > children ) { super( children ) ; this.location = location ; this.nodekind = nodeKind ; this.text = nodeKind.name() ; } public SimpleTree( final NodeKind nodeKind, final Iterable< ? extends SyntacticTree > children ) { this( nodeKind, null, children ) ; } @Override public SyntacticTree adopt( final Iterable< SyntacticTree > newChildren ) throws NullArgumentException { if( nodekind == null ) { return new SimpleTree( getText(), getLocation(), newChildren ) ; } else { return new SimpleTree( getNodeKind(), getLocation(), newChildren ) ; } } @Override public Iterable< ? extends SyntacticTree > getChildren() { final Iterable< ? extends SyntacticTree > children = super.getChildren() ; if( null == children ) { return ImmutableList.of() ; } else { return children ; } } @Override public String getText() { return text; } @Override public String toStringTree() { final StringBuilder buffer = new StringBuilder() ; final boolean shouldWrap = getChildCount() > 0 ; if( shouldWrap ) { buffer.append( "(" ) ; } buffer.append( getText() ) ; if( getChildCount() > 0 ) { buffer.append( " " ) ; boolean first = true ; for( final SyntacticTree tree : getChildren() ) { if( ! first ) { buffer.append( " " ) ; } buffer.append( tree.toStringTree() ) ; first = false ; } } if( shouldWrap ) { buffer.append( ")" ) ; } return buffer.toString() ; } @Override public Location getLocation() { return location ; } @Override public NodeKind getNodeKind() { return nodekind ; } @Override public boolean isOneOf( final NodeKind... kinds ) { boolean equalityByKind = false ; for( final NodeKind kind : kinds ) { if( kind == getNodeKind() ) { equalityByKind = true ; break ; } } /* boolean equalityByName = false ; if( NodeKindTools.rootHasNodeKindName( this ) ) { for( final NodeKind kind : kinds ) { if( getText().equals( kind.name() ) ) { equalityByName = true ; break ; } } } if( equalityByKind != equalityByName ) { throw new IllegalStateException() ; } */ return equalityByKind ; } /** * Is is possible to remove this kind of duplicate code? * * @see #isOneOf(org.novelang.parser.NodeKind...) */ @Override public boolean isOneOf( final Set< NodeKind > kinds ) { final boolean equalityByKind = kinds.contains( getNodeKind() ) ; /* boolean equalityByName = false ; if( NodeKindTools.rootHasNodeKindName( this ) ) { for( final NodeKind kind : kinds ) { if( getText().equals( kind.name() ) ) { equalityByName = true ; break ; } } } if( equalityByKind != equalityByName ) { throw new IllegalStateException() ; } */ return equalityByKind ; } @Override public Class< ? extends SyntacticTree > getStorageType() { return SyntacticTree.class ; } @Override public String toString() { return ClassUtils.getShortClassName( getClass() ) + "[" + text + "]" ; } }