/* * Copyright (C) 2010 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.clearsilver.jsilver.data; import com.google.clearsilver.jsilver.autoescape.EscapeMode; import java.io.IOException; import java.util.Iterator; import java.util.Map; /** * Class that wraps a Data object and exports the same interface. Useful for extending the * capabilities of an existing implementation. */ public class DelegatedData implements Data { private final Data delegate; public DelegatedData(Data delegate) { if (delegate == null) { throw new NullPointerException("Delegate Data must not be null."); } this.delegate = delegate; } /** * Subclasses will want to override this method to return a Data object of their specific type. * * @param newDelegate the Data object to wrap with a new delegator * @return a DelegateData type or subclass. */ protected DelegatedData newInstance(Data newDelegate) { return newDelegate == null ? null : new DelegatedData(newDelegate); } protected Data getDelegate() { return delegate; } protected static Data unwrap(Data data) { if (data instanceof DelegatedData) { data = ((DelegatedData) data).getDelegate(); } return data; } @Override public String getName() { return getDelegate().getName(); } @Override public String getValue() { return getDelegate().getValue(); } @Override public int getIntValue() { return getDelegate().getIntValue(); } @Override public boolean getBooleanValue() { return getDelegate().getBooleanValue(); } @Override public void setValue(String value) { getDelegate().setValue(value); } @Override public String getFullPath() { return getDelegate().getFullPath(); } @Override public void setAttribute(String key, String value) { getDelegate().setAttribute(key, value); } @Override public String getAttribute(String key) { return getDelegate().getAttribute(key); } @Override public boolean hasAttribute(String key) { return getDelegate().hasAttribute(key); } @Override public int getAttributeCount() { return getDelegate().getAttributeCount(); } @Override public Iterable> getAttributes() { return getDelegate().getAttributes(); } @Override public Data getRoot() { return newInstance(getDelegate().getRoot()); } @Override public Data getParent() { return newInstance(getDelegate().getParent()); } @Override public boolean isFirstSibling() { return getDelegate().isFirstSibling(); } @Override public boolean isLastSibling() { return getDelegate().isLastSibling(); } @Override public Data getNextSibling() { return newInstance(getDelegate().getNextSibling()); } @Override public int getChildCount() { return getDelegate().getChildCount(); } /** * Wrapping implementation of iterator that makes sure any Data object returned by the underlying * iterator is wrapped with the right DelegatedData type. */ protected class DelegatedIterator implements Iterator { private final Iterator iterator; DelegatedIterator(Iterator iterator) { this.iterator = iterator; } public boolean hasNext() { return iterator.hasNext(); } public DelegatedData next() { return newInstance(iterator.next()); } public void remove() { iterator.remove(); } } /** * Subclasses can override this method to return specialized child iterators. For example, if they * don't want to support the remove() operation. * * @return Iterator of children of delegate Data object that returns wrapped Data nodes. */ protected Iterator newChildIterator() { return new DelegatedIterator(getDelegate().getChildren().iterator()); } /** * Single Iterable object for each node. All it does is return a DelegatedIterator when asked for * iterator. */ private final Iterable delegatedIterable = new Iterable() { public Iterator iterator() { return newChildIterator(); } }; @Override public Iterable getChildren() { return delegatedIterable; } @Override public Data getChild(String path) { return newInstance(getDelegate().getChild(path)); } @Override public Data createChild(String path) { return newInstance(getDelegate().createChild(path)); } @Override public void removeTree(String path) { getDelegate().removeTree(path); } @Override public void setSymlink(String sourcePath, String destinationPath) { getDelegate().setSymlink(sourcePath, destinationPath); } @Override public void setSymlink(String sourcePath, Data destination) { destination = unwrap(destination); getDelegate().setSymlink(sourcePath, destination); } @Override public void setSymlink(Data symLink) { symLink = unwrap(symLink); getDelegate().setSymlink(symLink); } @Override public Data getSymlink() { return newInstance(getDelegate().getSymlink()); } @Override public void copy(String toPath, Data from) { from = unwrap(from); getDelegate().copy(toPath, from); } @Override public void copy(Data from) { from = unwrap(from); getDelegate().copy(from); } @Override public String getValue(String path, String defaultValue) { return getDelegate().getValue(path, defaultValue); } @Override public int getIntValue(String path, int defaultValue) { return getDelegate().getIntValue(path, defaultValue); } @Override public String getValue(String path) { return getDelegate().getValue(path); } @Override public int getIntValue(String path) { return getDelegate().getIntValue(path); } @Override public boolean getBooleanValue(String path) { return getDelegate().getBooleanValue(path); } @Override public void setValue(String path, String value) { getDelegate().setValue(path, value); } @Override public String toString() { return getDelegate().toString(); } @Override public void toString(StringBuilder out, int indent) { getDelegate().toString(out, indent); } @Override public void write(Appendable out, int indent) throws IOException { getDelegate().write(out, indent); } @Override public void optimize() { getDelegate().optimize(); } @Override public void setEscapeMode(EscapeMode mode) { getDelegate().setEscapeMode(mode); } @Override public EscapeMode getEscapeMode() { return getDelegate().getEscapeMode(); } }