/* * Copyright 2011-2013 HTTL Team. * * 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 httl.spi.translators.templates; import httl.*; import httl.spi.Converter; import java.io.*; import java.text.ParseException; import java.util.*; /** * Adaptive Template. (SPI, Prototype, ThreadSafe) * * @author Liang Fei (liangfei0201 AT gmail DOT com) * @see httl.Engine#getTemplate(String) */ public class AdaptiveTemplate implements Template, Serializable { private static final long serialVersionUID = 3094907176375413567L; private final Template writerTemplate; private final Template streamTemplate; private final Converter<Object, Object> outConverter; private Map<String, Template> macros; public AdaptiveTemplate(Template writerTemplate, Template streamTemplate, Converter<Object, Object> outConverter) { if (writerTemplate == null) throw new IllegalArgumentException("writer template == null"); if (streamTemplate == null) throw new IllegalArgumentException("stream template == null"); this.writerTemplate = writerTemplate; this.streamTemplate = streamTemplate; this.outConverter = outConverter; } public String getName() { return writerTemplate.getName(); } public String getEncoding() { return writerTemplate.getEncoding(); } public Locale getLocale() { return writerTemplate.getLocale(); } public long getLastModified() { return writerTemplate.getLastModified(); } public long getLength() { return writerTemplate.getLength(); } public String getSource() throws IOException { return writerTemplate.getSource(); } public Reader openReader() throws IOException { return writerTemplate.openReader(); } public InputStream openStream() throws IOException { return streamTemplate.openStream(); } public Engine getEngine() { return writerTemplate.getEngine(); } public Object evaluate() throws ParseException { // Context.getOut() only OutputStream or Writer if (Context.getContext().getOut() instanceof OutputStream) { return streamTemplate.evaluate(); } else { return writerTemplate.evaluate(); } } public Object evaluate(Object context) throws ParseException { // Context.getOut() only OutputStream or Writer if (Context.getContext().getOut() instanceof OutputStream) { return streamTemplate.evaluate(context); } else { return writerTemplate.evaluate(context); } } public void render() throws IOException, ParseException { render(Context.getContext().getOut()); } public void render(Object out) throws IOException, ParseException { if (out instanceof OutputStream) { streamTemplate.render(out); } else if (out instanceof Writer) { writerTemplate.render(out); } else { out = outConverter.convert(out, getVariables()); if (out instanceof OutputStream) { streamTemplate.render(out); } else { writerTemplate.render(out); } } } public void render(Object context, Object out) throws IOException, ParseException { if (out instanceof OutputStream) { streamTemplate.render(context, out); } else if (out instanceof Writer) { writerTemplate.render(context, out); } else { out = outConverter.convert(out, getVariables()); if (out instanceof OutputStream) { streamTemplate.render(context, out); } else { writerTemplate.render(context, out); } } } public Map<String, Class<?>> getVariables() { return writerTemplate.getVariables(); } public Map<String, Template> getMacros() { if (macros == null) { // allow duplicate on concurrent Map<String, Template> map = new HashMap<String, Template>(); Map<String, Template> writerMacros = writerTemplate.getMacros(); Map<String, Template> streamMacros = streamTemplate.getMacros(); for (Map.Entry<String, Template> entry : writerMacros.entrySet()) { map.put(entry.getKey(), new AdaptiveTemplate(entry.getValue(), streamMacros.get(entry.getKey()), outConverter)); } macros = Collections.unmodifiableMap(map); } return macros; } public int getOffset() { return writerTemplate.getOffset(); } public boolean isMacro() { return writerTemplate.isMacro(); } public void accept(Visitor visitor) throws IOException, ParseException { writerTemplate.accept(visitor); } public Template getParent() { return writerTemplate.getParent(); } public List<Node> getChildren() { return writerTemplate.getChildren(); } @Override public String toString() { return writerTemplate.toString(); } }