/*
* Copyright (c) 2014-2015 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.zest;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import org.json.JSONException;
import org.qi4j.api.structure.ApplicationDescriptor;
import org.qi4j.bootstrap.ApplicationAssembler;
import org.qi4j.bootstrap.Energy4Java;
import org.qi4j.bootstrap.builder.ApplicationBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Plugin for Zest Application.
* <p>
* See the Zest documentation at <a href="https://zest.apache.org/">zest.apache.org</a>.
*/
public class ZestPlugin
implements io.werval.api.Plugin<org.qi4j.api.structure.Application>
{
private static final Logger LOG = LoggerFactory.getLogger( ZestPlugin.class );
private org.qi4j.api.structure.Application zestApplication;
@Override
public Class<org.qi4j.api.structure.Application> apiType()
{
return org.qi4j.api.structure.Application.class;
}
@Override
public org.qi4j.api.structure.Application api()
{
return zestApplication;
}
@Override
public void onActivate( io.werval.api.Application application )
throws io.werval.api.exceptions.ActivationException
{
boolean hasAssembler = application.config().has( "zest.assembler" );
boolean hasAssembly = application.config().has( "zest.assembly" );
if( hasAssembler && hasAssembly )
{
throw new io.werval.api.exceptions.ActivationException(
"Zest Plugin cannot have both 'zest.assembler' and 'zest.assembly' configuration properties set, "
+ "remove one and retry."
);
}
if( !hasAssembler && !hasAssembly )
{
LOG.warn(
"Zest Plugin has no 'zest.assembler' nor 'zest.assembly' configuration property set. "
+ "Zest Application will not be created and activated."
);
return;
}
try
{
if( hasAssembler )
{
String assembler = application.config().string( "zest.assembler" );
ApplicationAssembler appAssembler = createApplicationAssembler( application, assembler );
Energy4Java zest = new Energy4Java();
ApplicationDescriptor model = zest.newApplicationModel( appAssembler );
zestApplication = model.newInstance( zest.api() );
zestApplication.activate();
LOG.debug( "Zest Application assembled from '{}' successfuly activated", assembler );
}
else
{
// TODO Support application modes!
String assembly = application.config().string( "zest.assembly" );
try( InputStream json = application.classLoader().getResourceAsStream( assembly ) )
{
zestApplication = ApplicationBuilder.fromJson( json ).newApplication();
}
LOG.debug( "Zest Application assembled from '{}' successfuly activated", assembly );
}
}
catch( JSONException | IOException |
org.qi4j.bootstrap.AssemblyException | org.qi4j.api.activation.ActivationException ex )
{
throw new io.werval.api.exceptions.ActivationException( ex.getMessage(), ex );
}
}
private ApplicationAssembler createApplicationAssembler( io.werval.api.Application application, String assembler )
{
try
{
Class<?> assemblerClass = application.classLoader().loadClass( assembler );
if( !ApplicationAssembler.class.isAssignableFrom( assemblerClass ) )
{
throw new IllegalArgumentException( assembler + " is not an ApplicationAssembler." );
}
try
{
org.qi4j.api.structure.Application.Mode mode;
switch( application.mode() )
{
case DEV:
mode = org.qi4j.api.structure.Application.Mode.development;
break;
case TEST:
mode = org.qi4j.api.structure.Application.Mode.test;
break;
case PROD:
default:
mode = org.qi4j.api.structure.Application.Mode.production;
break;
}
return (ApplicationAssembler) assemblerClass
.getConstructor( org.qi4j.api.structure.Application.Mode.class )
.newInstance( mode );
}
catch( NoSuchMethodException ex )
{
return (ApplicationAssembler) assemblerClass.newInstance();
}
}
catch( ClassNotFoundException | InstantiationException | IllegalAccessException | InvocationTargetException ex )
{
throw new io.werval.api.exceptions.ActivationException( ex.getMessage(), ex );
}
}
@Override
public void onPassivate( io.werval.api.Application application )
{
if( zestApplication != null )
{
try
{
zestApplication.passivate();
}
catch( org.qi4j.api.activation.PassivationException ex )
{
throw new io.werval.api.exceptions.PassivationException( ex.getMessage(), ex );
}
finally
{
zestApplication = null;
}
}
}
}