/*
* Copyright 2014 cruxframework.org.
*
* 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 org.cruxframework.crux.core.rebind.ioc;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.Map.Entry;
import org.cruxframework.crux.core.client.ioc.IoCContainerException;
import org.cruxframework.crux.core.client.ioc.IoCResource.Scope;
import org.cruxframework.crux.core.client.ioc.IocContainer;
import org.cruxframework.crux.core.client.ioc.IocProvider;
import org.cruxframework.crux.core.client.ioc.RuntimeIoCContainer;
import org.cruxframework.crux.core.client.utils.EscapeUtils;
import org.cruxframework.crux.core.client.utils.StringUtils;
import org.cruxframework.crux.core.ioc.IocConfig;
import org.cruxframework.crux.core.ioc.IocConfigImpl;
import org.cruxframework.crux.core.rebind.CruxGeneratorException;
import org.cruxframework.crux.core.rebind.GeneratorProperties;
import org.cruxframework.crux.core.rebind.context.RebindContext;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
/**
* @author Thiago da Rosa de Bustamante
*
*/
public class RuntimeContainerProxyCreator extends IocContainerRebind
{
public RuntimeContainerProxyCreator(RebindContext ctx, JClassType baseIntf)
{
super(ctx, null, getDeviceFeatures(ctx));
}
@Override
protected void generateProxyFields(SourcePrinter srcWriter) throws CruxGeneratorException
{
super.generateProxyFields(srcWriter);
srcWriter.println("private IocContainer baseContainer;");
}
@Override
protected void generateProxyContructor(SourcePrinter srcWriter) throws CruxGeneratorException
{
srcWriter.println("public "+getProxySimpleName()+"(){");
srcWriter.println("}");
}
@Override
protected void generateProxyMethods(SourcePrinter srcWriter) throws CruxGeneratorException
{
super.generateProxyMethods(srcWriter);
generateGetMethod(srcWriter);
generateGetScopedMethod(srcWriter);
generateSetContainerMethod(srcWriter);
generateGetScopeMethod(srcWriter);
}
private void generateSetContainerMethod(SourcePrinter srcWriter)
{
srcWriter.println("public void setIoCContainer(IocContainer iocContainer) {");
srcWriter.println("baseContainer = iocContainer;");
srcWriter.println("}");
}
private void generateGetScopeMethod(SourcePrinter srcWriter)
{
srcWriter.println("protected IocScope _getScope(Scope scope){");
srcWriter.println("return (baseContainer==null?null:baseContainer._getScope(scope));");
srcWriter.println("}");
}
protected void generateGetMethod(SourcePrinter srcWriter)
{
srcWriter.println("public <T> T get(Class<T> clazz){");
srcWriter.println("String className = clazz.getName();");
Iterator<Entry<String, IocConfig<?>>> classes = configurations.entrySet().iterator();
boolean needsElse = false;
while (classes.hasNext())
{
Entry<String, IocConfig<?>> entry = classes.next();
IocConfigImpl<?> iocConfig = (IocConfigImpl<?>)entry.getValue();
String className = entry.getKey();
if (iocConfig.isRuntimeAccessible())
{
if (needsElse)
{
srcWriter.print("else ");
}
needsElse = true;
srcWriter.println("if (StringUtils.unsafeEquals(className, "+EscapeUtils.quote(className)+")){");
srcWriter.println("return (T) get"+className.replace('.', '_')+"("+Scope.class.getCanonicalName()+"."+iocConfig.getScope().name()+",null);");
srcWriter.println("}");
}
}
srcWriter.println("throw new IoCContainerException(\"Class not bound to IoCContainer [\"+className+\"]\");");
srcWriter.println("}");
}
protected void generateGetScopedMethod(SourcePrinter srcWriter)
{
srcWriter.println("public <T> T get(Class<T> clazz, Scope scope, String subscope){");
srcWriter.println("String className = clazz.getName();");
Iterator<Entry<String, IocConfig<?>>> classes = configurations.entrySet().iterator();
boolean needsElse = false;
while (classes.hasNext())
{
Entry<String, IocConfig<?>> entry = classes.next();
IocConfigImpl<?> iocConfig = (IocConfigImpl<?>)entry.getValue();
String className = entry.getKey();
if (iocConfig.isRuntimeAccessible())
{
if (needsElse)
{
srcWriter.print("else ");
}
needsElse = true;
srcWriter.println("if (StringUtils.unsafeEquals(className, "+EscapeUtils.quote(className)+")){");
srcWriter.println("return (T) get"+className.replace('.', '_')+"(scope, subscope);");
srcWriter.println("}");
}
}
srcWriter.println("throw new IoCContainerException(\"Class not bound to IoCContainer [\"+className+\"]\");");
srcWriter.println("}");
}
@Override
protected String[] getImports()
{
String[] imports = new String[] {
org.cruxframework.crux.core.client.screen.views.View.class.getCanonicalName(),
GWT.class.getCanonicalName(),
IoCContainerException.class.getCanonicalName(),
Scope.class.getCanonicalName(),
StringUtils.class.getCanonicalName(),
IocContainer.class.getCanonicalName()
};
return imports;
}
@Override
protected SourcePrinter getSourcePrinter()
{
String packageName = IocProvider.class.getPackage().getName();
PrintWriter printWriter = context.getGeneratorContext().tryCreate(context.getLogger(), packageName, getProxySimpleName());
if (printWriter == null)
{
return null;
}
ClassSourceFileComposerFactory composerFactory = new ClassSourceFileComposerFactory(packageName, getProxySimpleName());
String[] imports = getImports();
for (String imp : imports)
{
composerFactory.addImport(imp);
}
composerFactory.addImplementedInterface(RuntimeIoCContainer.class.getCanonicalName());
return new SourceCodePrinter(composerFactory.createSourceWriter(context.getGeneratorContext(), printWriter), context.getLogger());
}
/**
*
* @return
*/
private static String getDeviceFeatures(RebindContext context)
{
return GeneratorProperties.readSelectionPropertyValue(context, GeneratorProperties.DEVICE_FEATURES);
}
}