/* * Copyright 2013 eXo Platform SAS * * 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 juzu.impl.plugin.template.metamodel; import juzu.impl.common.Resource; import juzu.impl.common.Timestamped; import juzu.impl.common.Tools; import juzu.impl.compiler.ProcessingException; import juzu.impl.compiler.ProcessingContext; import juzu.impl.template.spi.ParseContext; import juzu.impl.template.spi.TemplateException; import juzu.impl.template.spi.TemplateProvider; import juzu.impl.template.spi.ProcessContext; import juzu.impl.template.spi.TemplateModel; import juzu.impl.common.MethodInvocation; import juzu.impl.common.Path; import juzu.template.TagHandler; import javax.tools.FileObject; import java.io.Serializable; import java.nio.charset.Charset; import java.util.Collections; import java.util.Map; /** @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a> */ class MetaModelProcessContext extends ProcessContext { /** . */ private AbstractContainerMetaModel owner; /** . */ private final ProcessingContext env; /** . */ private final TemplateMetaModel metaModel; MetaModelProcessContext(AbstractContainerMetaModel owner, TemplateMetaModel metaModel) { this.owner = owner; this.env = owner.application.getProcessingContext(); this.metaModel = metaModel; } void resolve(final TemplateMetaModel metaModel) throws TemplateException { resolveTemplate(metaModel.path); } @Override public TagHandler resolveTagHandler(String name) { return owner.resolveTagHandler(name); } @Override protected Path.Absolute resolvePath(Path.Relative path) { return owner.resolvePath(path); } public MethodInvocation resolveMethodInvocation(String typeName, String methodName, Map<String, String> parameterMap) throws ProcessingException { return owner.getApplication().resolveMethodInvocation(typeName, methodName, parameterMap); } @Override public Timestamped<Resource> resolveResource(Path.Absolute path) { FileObject resource = owner.application.resolveResource(path); if (resource != null) { try { byte[] bytes = Tools.bytes(resource.openInputStream()); long lastModified = resource.getLastModified(); return new Timestamped<Resource>(lastModified, new Resource(bytes, Charset.defaultCharset())); } catch (Exception e) { env.info("Could not get resource content " + path.getCanonical(), e); } } return null; } public Path.Absolute resolveTemplate(Path path) throws TemplateException { Path.Absolute absolute; if (path instanceof Path.Relative) { absolute = resolvePath((Path.Relative)path); } else { absolute = (Path.Absolute)path; } return resolveTemplate(absolute); } private <M extends Serializable> Path.Absolute resolveTemplate(Path.Absolute path) throws TemplateException { Template template; if (path.equals(metaModel.path)) { template = metaModel; } else { template = owner.add(path, Collections.<TemplateRefMetaModel>singletonList(this.metaModel)); } if (template instanceof TemplateMetaModel) { TemplateMetaModel tmm = (TemplateMetaModel)template; if (tmm.templateModel == null) { Timestamped<Resource> resource = resolveResource(path); if (resource == null) { throw TemplateMetaModel.TEMPLATE_NOT_RESOLVED.failure(path); } else { TemplateProvider<M> provider = (TemplateProvider<M>)owner.resolveTemplateProvider(path.getExt()); M templateAST; try { templateAST = provider.parse(new ParseContext(), resource.getObject().getCharSequence()); } catch (TemplateException e1) { throw TemplateMetaModel.TEMPLATE_SYNTAX_ERROR.failure(path).initCause(e1); } TemplateModel<M> templateModel = new TemplateModel<M>( templateAST, path, resource.getTime(), Tools.md5(resource.getObject().getBytes())); tmm.templateModel = templateModel; try { provider.process(new MetaModelProcessContext(owner, tmm), templateModel); } catch (TemplateException e) { throw TemplateMetaModel.TEMPLATE_VALIDATION_ERROR.failure(path); } } } } return path; } }