/**
* Copyright (C) 2013 Schneider-Electric
*
* This file is part of "Mind Compiler" 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: mind@ow2.org
*
* Authors: Stephane SEYVOZ (Assystem)
* Contributors:
*/
package org.ow2.mind.preproc;
import static org.ow2.mind.PathHelper.fullyQualifiedNameToPath;
import static org.ow2.mind.adl.ast.ASTHelper.getNumberOfElement;
import java.io.File;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.objectweb.fractal.adl.ADLException;
import org.objectweb.fractal.adl.Definition;
import org.objectweb.fractal.adl.interfaces.Interface;
import org.objectweb.fractal.adl.types.TypeInterface;
import org.objectweb.fractal.adl.types.TypeInterfaceUtil;
import org.ow2.mind.adl.ast.ImplementationContainer;
import org.ow2.mind.adl.ast.Source;
import org.ow2.mind.adl.idl.InterfaceDefinitionDecorationHelper;
import org.ow2.mind.adl.implementation.ImplementationLocator;
import org.ow2.mind.idl.ast.InterfaceDefinition;
import org.ow2.mind.idl.ast.Method;
import org.ow2.mind.io.OutputFileLocator;
public class ImplementedMethodsHelper {
public static Source getDefinitionSourceFromPath(
final ImplementationLocator implLocatorItf,
final OutputFileLocator outputFileLocatorItf,
final Definition definition, final String mppSourceFileName,
final Map<Object, Object> context) {
int i = 0;
URL sourceFileURL = null;
String implSuffix = null;
File currSrcFile = null;
final ImplementationContainer container = (ImplementationContainer) definition;
final File sourceFile = new File(mppSourceFileName);
/*
* In the case of inlined C code, the whole validity of this algorithm is
* based on the container.getSources() order staying the same as in {@link
* BasicDefinitionCompiler#visitImplementation}, giving numbers to the
* implementations, including the inlined C code, which is extracted to
* _impl<i>.c files in the output folder.
*/
for (final Source currSource : container.getSources()) {
implSuffix = "_impl" + i;
try {
// inlined C code ?
if (currSource.getPath() == null) {
if (currSource.getCCode() != null) {
// Search in BasicDefinitionCompiler this comment:
// "Implementation code is inlined in the ADL. Dump it in a file."
currSrcFile = outputFileLocatorItf
.getCSourceOutputFile(
fullyQualifiedNameToPath(definition.getName(), implSuffix,
".c"), context);
} else
return null; // Error case
} else {
sourceFileURL = implLocatorItf.findSource(currSource.getPath(),
context);
currSrcFile = new File(sourceFileURL.toURI());
}
if (currSrcFile.equals(sourceFile)) return currSource;
} catch (final URISyntaxException e) {
e.printStackTrace();
}
i++;
}
return null;
}
/**
*
*/
public static final String IMPLEMENTED_METHODS = "implemented-methods";
/**
* @param itf
* @return
*/
public static List<String> getImplementedMethods(final Interface itf) {
final List<String> methNamesList = (List<String>) itf
.astGetDecoration(IMPLEMENTED_METHODS);
if (methNamesList == null) return new ArrayList<String>();
return methNamesList;
}
/**
* @param itf
* @return
*/
public static boolean allInterfaceMethodsAreImplemented(final Interface itf) {
final List<String> unimplementedMethods = getInterfaceUnimplementedMethods(itf);
if (unimplementedMethods.isEmpty()) return true;
return false;
}
/**
* @param itf
* @return
*/
public static List<String> getInterfaceUnimplementedMethods(
final Interface itf) {
final List<String> implMeths = getImplementedMethods(itf);
final List<String> result = new ArrayList<String>();
InterfaceDefinition itfDef;
// assume that itfDef is already loaded
try {
itfDef = InterfaceDefinitionDecorationHelper
.getResolvedInterfaceDefinition((TypeInterface) itf, null, null);
} catch (final ADLException e) {
return result;
}
if (itfDef == null) return result;
final Method[] methods = itfDef.getMethods();
for (final Method currMethod : methods) {
if (!implMeths.contains(currMethod.getName()))
result.add(currMethod.getName());
}
return result;
}
/**
* @param itf
* @return
*/
public static Map<Integer, List<String>> getCollectionInterfaceUnimplementedMethods(
final Interface itf) {
assert TypeInterfaceUtil.isCollection(itf);
final int nbElement = getNumberOfElement(itf);
final Map<Integer, List<String>> implMeths = getCollectionImplementedMethods(itf);
final Map<Integer, List<String>> result = new TreeMap<Integer, List<String>>();
InterfaceDefinition itfDef;
// assume that itfDef is already loaded
try {
itfDef = InterfaceDefinitionDecorationHelper
.getResolvedInterfaceDefinition((TypeInterface) itf, null, null);
} catch (final ADLException e) {
return result;
}
if (itfDef == null) return result;
final Method[] methods = itfDef.getMethods();
for (Integer i = 0; i < nbElement; i++) {
for (final Method currMethod : methods) {
List<String> implMethsByIdx = implMeths.get(i);
if (implMethsByIdx == null) {
implMethsByIdx = new ArrayList<String>();
implMeths.put(i, implMethsByIdx);
}
if (!implMethsByIdx.contains(currMethod.getName())) {
List<String> resultMethsByIdx = result.get(i);
if (resultMethsByIdx == null)
resultMethsByIdx = new ArrayList<String>();
resultMethsByIdx.add(currMethod.getName());
result.put(i, resultMethsByIdx);
}
}
}
return result;
}
public static void addImplementedMethod(final Interface itf,
final String methName) {
final List<String> values = getImplementedMethods(itf);
values.add(methName);
setImplementedMethods(itf, values);
}
public static void addCollectionImplementedMethod(final Interface itf,
final Integer idxInt, final String methName) {
final Map<Integer, List<String>> values = getCollectionImplementedMethods(itf);
assert TypeInterfaceUtil.isCollection(itf);
List<String> implMethNamesForIdx = values.get(idxInt);
if (implMethNamesForIdx == null)
implMethNamesForIdx = new ArrayList<String>();
implMethNamesForIdx.add(methName);
values.put(idxInt, implMethNamesForIdx);
setCollectionImplementedMethods(itf, values);
}
private static void setCollectionImplementedMethods(final Interface itf,
final Map<Integer, List<String>> values) {
assert TypeInterfaceUtil.isCollection(itf);
itf.astSetDecoration(IMPLEMENTED_METHODS, values);
}
public static Map<Integer, List<String>> getCollectionImplementedMethods(
final Interface itf) {
assert TypeInterfaceUtil.isCollection(itf);
final Map<Integer, List<String>> idxMethNamesMap = (Map<Integer, List<String>>) itf
.astGetDecoration(IMPLEMENTED_METHODS);
if (idxMethNamesMap == null) return new TreeMap<Integer, List<String>>();
return idxMethNamesMap;
}
/**
* @param itf
* @param methNamesList
*/
public static void setImplementedMethods(final Interface itf,
final List<String> methNamesList) {
itf.astSetDecoration(IMPLEMENTED_METHODS, methNamesList);
}
/**
*
*/
public static final String SOURCE_VISITED = "source-visited";
/**
* @param source
*/
public static void setSourceVisited(final Source source) {
source.astSetDecoration(SOURCE_VISITED, Boolean.TRUE);
}
/**
* @param source
* @return
*/
public static boolean hasSourceBeenVisited(final Source source) {
final Boolean value = (Boolean) source.astGetDecoration(SOURCE_VISITED);
if (value == null) return false;
return value;
}
/**
* @param container
* @return
*/
public static boolean haveAllSourcesBeenVisited(
final ImplementationContainer container) {
for (final Source currSource : container.getSources())
if (!hasSourceBeenVisited(currSource)) return false;
return true;
}
}