blob: 06c08cdd0354817bfcb4c78f7bf5bcbb4adc78c2 [file] [log] [blame]
/*
* 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<Map.Entry<String, String>> 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<DelegatedData> {
private final Iterator<? extends Data> iterator;
DelegatedIterator(Iterator<? extends Data> 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<DelegatedData> 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<DelegatedData> delegatedIterable = new Iterable<DelegatedData>() {
public Iterator<DelegatedData> iterator() {
return newChildIterator();
}
};
@Override
public Iterable<? extends Data> 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();
}
}