/**
* EasySOA
* Copyright 2011 Open Wide
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Contact : easysoa-dev@googlegroups.com
*/
package org.easysoa.frascati;
import java.net.URL;
//import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.namespace.QName;
import org.easysoa.frascati.api.FraSCAtiServiceItf;
//import org.easysoa.frascati.api.RegistryItf;
import org.easysoa.frascati.api.ScaImporterIntermediaryItf;
import org.easysoa.frascati.api.ScaImporterRecipientItf;
//import org.easysoa.frascati.api.intent.ComponentIntentObserverItf;
import org.easysoa.frascati.api.intent.ParserIntentObserverItf;
//import org.easysoa.frascati.api.intent.ProcessingIntentObserverItf;
import org.easysoa.frascati.processor.EasySOAProcessingContext;
import org.eclipse.stp.sca.Composite;
import org.objectweb.fractal.api.Component;
import org.objectweb.fractal.api.NoSuchInterfaceException;
import org.objectweb.fractal.api.control.ContentController;
import org.objectweb.fractal.api.control.IllegalLifeCycleException;
import org.objectweb.fractal.api.control.LifeCycleController;
import org.objectweb.fractal.api.control.NameController;
import org.osoa.sca.annotations.Reference;
import org.osoa.sca.annotations.Scope;
import org.osoa.sca.annotations.Service;
import org.ow2.frascati.assembly.factory.api.ClassLoaderManager;
import org.ow2.frascati.assembly.factory.api.CompositeManager;
import org.ow2.frascati.assembly.factory.api.ManagerException;
import org.ow2.frascati.assembly.factory.api.ProcessingMode;
import org.ow2.frascati.util.AbstractLoggeable;
import org.ow2.frascati.util.FrascatiClassLoader;
import org.ow2.frascati.util.io.IOUtils;
/**
* Implementation of the {@link FraSCAtiServiceItf}
*
* @author Christophe Munilla
*
*/
@Scope("COMPOSITE")
@Service(interfaces = { FraSCAtiServiceItf.class, ParserIntentObserverItf.class })
public class FraSCAtiService
extends AbstractLoggeable implements FraSCAtiServiceItf, ParserIntentObserverItf
{
// @Reference(name = "registry")
// private RegistryItf registry;
@Reference(name = "composite-manager")
private CompositeManager compositeManager;
/**
* The required CompositeManager
*/
@Reference(name = "classloader-manager")
private ClassLoaderManager classLoaderManager;
@Reference(name = "runtime-sca-importer")
private ScaImporterIntermediaryItf runtimeSCAImporter;
private static final Logger logger = Logger.getLogger(FraSCAtiService.class.getCanonicalName());
private List<String> warningMessages;
private List<String> errorMessages;
private Map<String,Composite> compositesMap;
private int errors;
private int warnings;
/**
* {@inheritDoc}
*
* @see org.easysoa.frascati.api.FraSCAtiServiceItf#getComposite(java.lang.String)
*/
public Composite getComposite(String compositeName)
throws FraSCAtiServiceException
{
Component component = null;
String componentName = IOUtils.pathLastPart(compositeName);
try
{
component = getComponent(
compositeManager.getTopLevelDomainComposite(),componentName);
} catch (Exception e)
{
logger.log(Level.SEVERE,e.getMessage(),e);
}
if(component != null )
{
return compositesMap.get(compositeName);
}
return null;
}
/**
* {@inheritDoc}
*
* @see org.easysoa.frascati.api.FraSCAtiServiceItf#processContribution(java.
* lang.String, int, java.net.URL[])
*/
public String[] processContribution(String contribution,
int processingMode, Properties properties, URL... urls) throws FraSCAtiServiceException
{
EasySOAProcessingContext processingContext =
new EasySOAProcessingContext(classLoaderManager.getClassLoader());
for(String propertyName : properties.stringPropertyNames()) {
processingContext.setContextualProperty(propertyName, properties.getProperty(propertyName));
}
FrascatiClassLoader fcl = (FrascatiClassLoader)processingContext.getClassLoader();
if(urls != null)
{
for(URL url : urls)
{
fcl.addUrl(url);
}
}
processingContext.setProcessingMode(resovleProcessingMode(processingMode));
ClassLoader current = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(fcl);
Component[] components;
try
{
components = compositeManager.processContribution(contribution,
processingContext);
} catch (ManagerException e)
{
logger.log(Level.SEVERE,e.getMessage(),e);
throw new FraSCAtiServiceException("Enable to process the '"
+ contribution + "' contribution");
}catch(Exception e)
{
logger.log(Level.SEVERE,e.getMessage(),e);
throw new FraSCAtiServiceException("Enable to process the '"
+ contribution + "' composite");
} finally
{
Thread.currentThread().setContextClassLoader(current);
this.warningMessages = processingContext.getWarningMessages();
this.errorMessages = processingContext.getErrorMessages();
this.errors = processingContext.getErrors();
this.warnings = processingContext.getWarnings();
}
if(components != null && components.length>0)
{
String[] processed = new String[components.length];
int currentComponentIndex = 0;
for(;currentComponentIndex<components.length;currentComponentIndex++)
{
try{
processed[currentComponentIndex] = ((NameController)components[
currentComponentIndex].getFcInterface(
"name-controller")).getFcName();
} catch(NoSuchInterfaceException e)
{
log.log(Level.WARNING,e.getMessage());
}
}
return processed;
} else
{
return new String[0];
}
}
/**
* {@inheritDoc}
*
* @see org.easysoa.frascati.api.FraSCAtiServiceItf#processContribution(java.
* lang.String)
*/
public String[] processContribution(String contribution)
throws FraSCAtiServiceException
{
return processContribution(contribution, FraSCAtiServiceItf.all, null);
}
/**
* {@inheritDoc}
*
* @see org.easysoa.frascati.api.FraSCAtiServiceItf#processComposite(java.lang
* .String, int, java.net.URL[])
*/
public Composite processComposite(String composite, int processingMode, Properties properties,
URL... urls) throws FraSCAtiServiceException
{
FrascatiClassLoader classLoader = new FrascatiClassLoader(
urls!=null?urls:new URL[0] , classLoaderManager.getClassLoader());
EasySOAProcessingContext processingContext = new EasySOAProcessingContext(
classLoader);
if(properties != null){
for(String propertyName : properties.stringPropertyNames()) {
processingContext.setContextualProperty(propertyName, properties.getProperty(propertyName));
}
}
processingContext.setProcessingMode(resovleProcessingMode(processingMode));
Component component = null;
try
{
component = compositeManager.processComposite(new QName(composite),
processingContext);
} catch (ManagerException e)
{
logger.log(Level.SEVERE,e.getMessage(),e);
throw new FraSCAtiServiceException("Enable to process the '"
+ composite + "' composite");
} catch(Exception e)
{
logger.log(Level.SEVERE,e.getMessage(),e);
throw new FraSCAtiServiceException("Enable to process the '"
+ composite + "' composite");
}
finally
{
this.warningMessages = processingContext.getWarningMessages();
this.errorMessages = processingContext.getErrorMessages();
this.errors = processingContext.getErrors();
this.warnings = processingContext.getWarnings();
}
if(component != null)
{
try{
return getComposite(((NameController)component.getFcInterface(
"name-controller")).getFcName());
} catch(NoSuchInterfaceException e)
{
log.log(Level.WARNING,e.getMessage());
}
} else if (processingContext.getRootComposite() != null) {
return processingContext.getRootComposite();
}
return null;
}
/**
* {@inheritDoc}
*
* @see org.easysoa.frascati.api.FraSCAtiServiceItf#processComposite(java.lang
* .String)
*/
public Composite processComposite(String composite)
throws FraSCAtiServiceException
{
return processComposite(composite, FraSCAtiServiceItf.all, new Properties());
}
/**
* {@inheritDoc}
*
* @see org.easysoa.frascati.api.FraSCAtiServiceItf#state(java.lang.String)
*/
public String state(String compositeName)
{
Component component = null;
try
{
component = getComponent(
compositeManager.getTopLevelDomainComposite(),compositeName);
} catch (Exception e)
{
logger.log(Level.SEVERE,e.getMessage(),e);
}
if (component != null)
{
try
{
LifeCycleController lcController = (LifeCycleController) component
.getFcInterface("lifecycle-controller");
return lcController.getFcState();
} catch (NoSuchInterfaceException e)
{
log.log(Level.WARNING,e.getMessage(),e);
}
}
return null;
}
/**
* {@inheritDoc}
*
* @see org.easysoa.frascati.api.FraSCAtiServiceItf#start(java.lang.String)
*/
public void start(String componentName)
{
Component component = null;
try
{
component = getComponent(
compositeManager.getTopLevelDomainComposite(),componentName);
} catch (Exception e)
{
logger.log(Level.SEVERE,e.getMessage(),e);
}
if (component != null)
{
try
{
LifeCycleController lcController = (LifeCycleController) component
.getFcInterface("lifecycle-controller");
if (!LifeCycleController.STARTED.equals(lcController
.getFcState()))
{
lcController.startFc();
}
} catch (NoSuchInterfaceException e)
{
logger.log(Level.SEVERE,e.getMessage(),e);
} catch (IllegalLifeCycleException e)
{
logger.log(Level.SEVERE,e.getMessage(),e);
}
}
}
/**
* {@inheritDoc}
*
* @see org.easysoa.frascati.api.FraSCAtiServiceItf#stop(java.lang.String)
*/
public void stop(String componentName)
{
Component component = null;
try
{
component = getComponent(
compositeManager.getTopLevelDomainComposite(),componentName);
} catch (Exception e)
{
logger.log(Level.SEVERE,e.getMessage(),e);
}
if (component != null)
{
try
{
LifeCycleController lcController = (LifeCycleController) component
.getFcInterface("lifecycle-controller");
if (!LifeCycleController.STOPPED.equals(lcController
.getFcState()))
{
lcController.stopFc();
}
} catch (NoSuchInterfaceException e)
{
logger.log(Level.SEVERE,e.getMessage(),e);
} catch (IllegalLifeCycleException e)
{
logger.log(Level.SEVERE,e.getMessage(),e);
}
}
}
/**
* {@inheritDoc}
*
* @see org.easysoa.frascati.api.FraSCAtiServiceItf#remove(java.lang.String)
*/
public void remove(String compositeName)
throws FraSCAtiServiceException
{
String componentName = IOUtils.pathLastPart(compositeName);
stop(componentName);
try
{
compositeManager.removeComposite(componentName);
} catch (ManagerException e)
{
logger.log(Level.SEVERE,e.getMessage(),e);
throw new FraSCAtiServiceException("Enable to remove the '"
+ componentName + "' component");
}
}
/**
* {@inheritDoc}
*
* @see org.easysoa.frascati.api.FraSCAtiServiceItf#getService(java.lang.String,
* java.lang.String, java.lang.Class)
*/
public <T> T getService(String componentName,
String serviceName, Class<T> serviceClass)
throws FraSCAtiServiceException
{
Component component = null;
try
{
component = getComponent(
compositeManager.getTopLevelDomainComposite(),componentName);
} catch (Exception e)
{
logger.log(Level.SEVERE,e.getMessage(),e);
}
if(component != null)
{
try
{
Object serviceFcInterface = component.getFcInterface(serviceName);
if (serviceClass.isInstance(serviceFcInterface)) {
// else FraSCAti compilation error "Type safety: Unchecked cast from Object to T"
// see http://stackoverflow.com/questions/15272855/java-generics-returning-a-list-depending-on-input
return serviceClass.cast(serviceFcInterface);
}
} catch (NoSuchInterfaceException e)
{
log.log(Level.WARNING,e.getMessage(),e);
}
} else
{
log.log(Level.WARNING,"Component '" + componentName + "' not found");
}
return null;
}
/**
* {@inheritDoc}
*
* @see org.easysoa.frascati.api.FraSCAtiServiceItf#getWarningMessages()
*/
public List<String> getWarningMessages()
{
return warningMessages;
}
/**
* {@inheritDoc}
*
* @see org.easysoa.frascati.api.FraSCAtiServiceItf#getErrors()
*/
public int getErrors()
{
return errors;
}
/**
* {@inheritDoc}
*
* @see org.easysoa.frascati.api.FraSCAtiServiceItf#getErrorMessages()
*/
public List<String> getErrorMessages()
{
return errorMessages;
}
/**
* {@inheritDoc}
*
* @see org.easysoa.frascati.api.FraSCAtiServiceItf#getWarnings()
*/
public int getWarnings()
{
return warnings;
}
/**
*
* @param mode
* @return
*/
private ProcessingMode resovleProcessingMode(int mode)
{
switch (mode)
{
case FraSCAtiServiceItf.parse:
return ProcessingMode.parse;
case FraSCAtiServiceItf.check:
return ProcessingMode.check;
case FraSCAtiServiceItf.generate:
return ProcessingMode.generate;
case FraSCAtiServiceItf.compile:
return ProcessingMode.compile;
case FraSCAtiServiceItf.instantiate:
return ProcessingMode.instantiate;
case FraSCAtiServiceItf.complete:
return ProcessingMode.complete;
case FraSCAtiServiceItf.start:
return ProcessingMode.start;
case FraSCAtiServiceItf.all:
return ProcessingMode.all;
default:
return null;
}
}
/**
* {@inheritDoc}
*
* @see org.easysoa.frascati.api.FraSCAtiServiceItf#
* setScaImporterRecipient(org.easysoa.frascati.api.ScaImporterRecipientItf)
*/
public void setScaImporterRecipient(ScaImporterRecipientItf recipient)
{
this.runtimeSCAImporter.setScaImporterRecipient(recipient);
}
/**
* Return the {@link Component} which path is passed on as a parameter if
* it exists in the ScaDomain (Top Level Domain Component of FraSCAti)
*
* @param componentName
* the name of the {@link Component} to return
* @return
* the {@link Component} if it exists, null otherwise
*/
private Component getComponent(Component currentComponent,
String componentPath) throws Exception
{
String[] componentPathElements = componentPath.split("/");
String lookFor = componentPathElements[0];
String next = null;
if(componentPathElements.length>1)
{
int n = 1;
StringBuilder nextSB = new StringBuilder();
for(;n<componentPathElements.length;n++)
{
nextSB.append(componentPathElements[n]);
if(n<componentPathElements.length - 1)
{
nextSB.append("/");
}
}
next = nextSB.toString();
}
ContentController contentController = (ContentController) currentComponent.getFcInterface(
"content-controller");
Component[] subComponents = contentController.getFcSubComponents();
if(subComponents == null)
{
return null;
}
for(Component component : subComponents)
{
NameController nameController = (NameController) component.getFcInterface(
"name-controller");
String name = (String) nameController.getFcName();
if(lookFor.equals(name))
{
if(next == null || next.length() ==0)
{
return component;
} else
{
return getComponent(component,next);
}
}
}
return null;
}
/**
* {@inheritDoc}
*
* @see org.easysoa.frascati.api.intent.ParserIntentObserverItf#
* compositeParsed(org.eclipse.stp.sca.Composite)
*/
public void compositeParsed(Composite composite)
{
if(compositesMap == null)
{
compositesMap = new HashMap<String,Composite>();
}
if(composite != null)
{
compositesMap.put(composite.getName(),composite);
}
}
}