/* * Copyright (c) 2014 the original author or authors * * 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 io.werval.modules.rythm; import java.net.URL; import io.werval.api.Application; import org.rythmengine.RythmEngine; import org.rythmengine.extension.ICodeType; import org.rythmengine.extension.ITemplateResourceLoader; import org.rythmengine.resource.ITemplateResource; import org.rythmengine.resource.ResourceLoaderBase; import org.rythmengine.resource.TemplateResourceBase; import org.rythmengine.utils.IO; import org.rythmengine.utils.S; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import static io.werval.util.Strings.withoutHead; /** * Named Rythm Template Resource Loader. */ /* package */ class NamedTemplateLoader extends ResourceLoaderBase implements ITemplateResourceLoader { private static final Logger LOG = LoggerFactory.getLogger( NamedTemplateLoader.class ); private final Application application; private final String root; /* package */ NamedTemplateLoader( Application application, String root ) { super(); this.application = application; this.root = root; } @Override public String getResourceLoaderRoot() { return root; } @Override public ITemplateResource load( String path ) { return new TemplateResource( path, application.classLoader(), this ); } private static final class TemplateResource implements ITemplateResource { private final ITemplateResourceLoader loader; private final URL url; private final String key; private String cache; private TemplateResource( String path, ClassLoader classLoader, ITemplateResourceLoader templateLoader ) { this.loader = templateLoader; // strip heading slash so path will work with classes in a JAR file path = withoutHead( path, "/" ); URL u = classLoader.getResource( path ); if( u == null ) { u = classLoader.getResource( loader.getResourceLoaderRoot() + "/" + path ); } url = u; key = path; } @Override public Object getKey() { return key; } @Override public ITemplateResourceLoader getLoader() { return loader; } @Override public boolean isValid() { return null != url; } @Override public ICodeType codeType( RythmEngine engine ) { return TemplateResourceBase.getTypeOfPath( engine, S.str( getKey() ) ); } @Override public String asTemplateContent() { if( null == cache ) { LOG.debug( "Loading '{}' template from {}", key, url ); cache = IO.readContentAsString( url ); } return cache; } @Override public String getSuggestedClassName() { String path = key; int colon = path.indexOf( ":" ); if( ++colon > 0 ) { path = path.substring( colon ); // strip the driver letter from windows path and scheme from the URL } while( path.startsWith( "/" ) ) { path = path.substring( 1 ); } while( path.startsWith( "\\" ) ) { path = path.substring( 1 ); } // replace characters that are invalid in a java identifier with '_' return path.replaceAll( "[.\\\\/ -]", "_" ); } @Override public boolean refresh() { return false; } @Override public boolean equals( Object obj ) { if( obj == this ) { return true; } if( null == obj ) { return false; } if( ITemplateResource.class.isAssignableFrom( obj.getClass() ) ) { return ( (ITemplateResource) obj ).getKey().equals( getKey() ); } return false; } @Override public int hashCode() { return getKey().hashCode(); } } }