...
 
Commits (4)
/**
* Copyright (C) 2016 Bonitasoft S.A.
* Bonitasoft, 32 rue Gustave Eiffel - 38000 Grenoble
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2.0 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.bonitasoft.studio.common.repository;
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import org.bonitasoft.studio.common.log.BonitaStudioLog;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.core.search.SearchMatch;
import org.eclipse.jdt.core.search.SearchParticipant;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.core.search.SearchRequestor;
import org.eclipse.jdt.launching.JavaRuntime;
public class JavaProjectClassLoader extends ClassLoader {
private final IJavaProject javaProject;
private static final String PROTOCOL_PREFIX = "file:///";
public JavaProjectClassLoader(IJavaProject project) {
super();
if (project == null || !project.exists())
throw new IllegalArgumentException("Invalid javaProject");
this.javaProject = project;
}
@Override
public Class findClass(String className) {
try {
final String[] classPaths = JavaRuntime.computeDefaultRuntimeClassPath(javaProject);
final URL[] urls = new URL[classPaths.length];
for (int i = 0; i < classPaths.length; i++)
urls[i] = new URL(PROTOCOL_PREFIX + computeForURLClassLoader(classPaths[i]));
try (final URLClassLoader loader = new URLClassLoader(urls);) {
final Class<?> classObject = loader.loadClass(className);
return classObject;
}
} catch (final Exception e) {
BonitaStudioLog.error(e);
}
return null;
}
public List<Class> findClasses(String classNamePattern) {
final List<Class> results = new ArrayList<>();
if (classNamePattern.endsWith(".java")) {
classNamePattern = classNamePattern.substring(0, classNamePattern.lastIndexOf("."));
}
// find exact matches first
findClasses(classNamePattern, results);
// and then everything else
if (!classNamePattern.endsWith("*")) {
classNamePattern += "*";
findClasses(classNamePattern, results);
}
return results;
}
public void findClasses(String classNamePattern, final List<Class> results) {
final SearchPattern pattern = SearchPattern.createPattern(classNamePattern,
IJavaSearchConstants.TYPE, IJavaSearchConstants.TYPE,
SearchPattern.R_PATTERN_MATCH);
final SearchEngine searchEngine = new SearchEngine();
final IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaProject[] { javaProject });
final SearchRequestor requestor = new SearchRequestor() {
@Override
public void acceptSearchMatch(SearchMatch match) {
IJavaElement e = (IJavaElement) match.getElement();
final String elementName = e.getElementName();
while (e != null) {
if (e instanceof IPackageFragment) {
final IPackageFragment pf = (IPackageFragment) e;
final String className = pf.getElementName() + "." + elementName;
final Class c = findClass(className);
if (c != null) {
boolean found = false;
for (final Class cr : results) {
if (cr.getName().equals(c.getName())) {
found = true;
break;
}
}
if (!found)
results.add(c);
}
}
e = e.getParent();
}
}
};
try {
searchEngine.search(
pattern,
new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() },
scope,
requestor,
null);
} catch (final CoreException e) {
}
}
public static IJavaProject[] findProject(final String className) {
final SearchPattern pattern = SearchPattern.createPattern(className,
IJavaSearchConstants.TYPE, IJavaSearchConstants.TYPE,
SearchPattern.R_EXACT_MATCH);
final List<IJavaProject> results = new ArrayList<>();
final IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
for (final IProject p : projects) {
try {
if (p.isOpen() && p.hasNature(JavaCore.NATURE_ID)) {
final IJavaProject javaProject = JavaCore.create(p);
final SearchEngine searchEngine = new SearchEngine();
final IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaProject[] { javaProject });
final SearchRequestor requestor = new SearchRequestor() {
@Override
public void acceptSearchMatch(SearchMatch match) {
IJavaElement e = (IJavaElement) match.getElement();
final String elementName = e.getElementName();
while (e != null) {
if (e instanceof IPackageFragment) {
final IPackageFragment pf = (IPackageFragment) e;
final String n = pf.getElementName() + "." + elementName;
if (className.equals(n))
results.add(javaProject);
}
e = e.getParent();
}
}
};
searchEngine.search(
pattern,
new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() },
scope,
requestor,
null);
}
} catch (final Exception e) {
}
}
return results.toArray(new IJavaProject[results.size()]);
}
private static String computeForURLClassLoader(String classpath) {
if (!classpath.endsWith("/")) {
final File file = new File(classpath);
if (file.exists() && file.isDirectory())
classpath = classpath.concat("/");
}
return classpath;
}
}
......@@ -32,7 +32,7 @@ public class ContractInputFunctions {
@Override
public List<String> apply(final ContractInput input) {
final List<String> ancestors = new ArrayList<String>();
final List<String> ancestors = new ArrayList<>();
EObject current = input;
while (current instanceof ContractInput) {
ancestors.add(((ContractInput) current).getName());
......@@ -49,16 +49,14 @@ public class ContractInputFunctions {
@Override
public List<String> apply(final ContractInput input) {
final List<String> ancestors = new ArrayList<String>();
final List<String> ancestors = new ArrayList<>();
EObject current = input;
while (current instanceof ContractInput
&& !(((ContractInput) current).isMultiple() && ((ContractInput) current).getType() == ContractInputType.COMPLEX)) {
do {
ancestors.add(((ContractInput) current).getName());
current = current.eContainer();
}
if (ancestors.isEmpty()) {
ancestors.add(input.getName());
}
} while (current instanceof ContractInput
&& !(((ContractInput) current).isMultiple()
&& ((ContractInput) current).getType() == ContractInputType.COMPLEX));
return reverse(ancestors);
}
......
......@@ -99,4 +99,9 @@ saving=Guardando...
taskBdmTips=Primero defina <a>las variables de negocio</a> y/o<a>los documentos</a> y luego haga clic en "Agregar datos...". Autom\u00e1ticamente se mapen las entradas de contrato a los datos y se crean operaciones para actualizar datos con valores de contrato.
poolBdmTips=Primero defina <a>las variables de negocio</a> y/o<a>los documentos</a> y luego haga clic en "Agregar datos...". Autom\u00e1ticamente se mapean las entradas de contrato a los datos y se crean operaciones para actualizar datos con valores de contrato.
creatingNewForm=Creating new form...
createDataFromContractChoice=Create data from contract
editDataFromContractChoice=Edit an existing data using contract and context when generating a Form from the contract
lazyFieldInAMultipleParentRelationHasBeenDeselect=%s.%s has been unselected. Generating an edition form for this field is not supported (lazy reference in a multiple parent).
aChildHasBeenUnselected=A child relation has been unselected.
moreInfoFormGenerationLink=More information about <a>Contract and Form generation</a>.
......@@ -99,4 +99,9 @@ saving=Enregistrement en cours...
taskBdmTips=Il est conseill\u00e9 de d'abord d\u00e9finir des <a>variables m\u00e9tier</a> et/ou des <a>documents</a> puis de cliquer sur \u00ab\u00a0Ajouter \u00e0 partir de donn\u00e9es...\u00a0\u00bb.\nCette fonction cr\u00e9era automatiquement le mapping entre inputs de contrat et donn\u00e9es. Elle cr\u00e9era aussi les op\u00e9rations de mise \u00e0 jour des donn\u00e9es avec les valeurs du contrat.
poolBdmTips=Il est conseill\u00e9 de d'abord d\u00e9finir des <a>variables m\u00e9tier</a> et/ou des <a>documents</a> puis de cliquer sur \u00ab\u00a0Ajouter \u00e0 partir de donn\u00e9es...\u00a0\u00bb.\nCette fonction cr\u00e9era automatiquement le mapping entre inputs de contrat et donn\u00e9es. Elle initialisera aussi les donn\u00e9es avec les valeurs du contrat.
creatingNewForm=Creating new form...
createDataFromContractChoice=Create data from contract
editDataFromContractChoice=Edit an existing data using contract and context when generating a Form from the contract
lazyFieldInAMultipleParentRelationHasBeenDeselect=%s.%s has been unselected. Generating an edition form for this field is not supported (lazy reference in a multiple parent).
aChildHasBeenUnselected=A child relation has been unselected.
moreInfoFormGenerationLink=More information about <a>Contract and Form generation</a>.
......@@ -99,4 +99,9 @@ saving=\u4fdd\u5b58\u4e2d...
taskBdmTips=\u6700\u521d\u306b<a>\u30d3\u30b8\u30cd\u30b9\u5909\u6570</a>\u3001\u304a\u3088\u3073/\u307e\u305f\u306f<a>\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8</a>\u3092\u5b9a\u7fa9\u3057\u3001\u300c\u30c7\u30fc\u30bf\u304b\u3089\u8ffd\u52a0...\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002\n\u5165\u529b\u30b3\u30f3\u30c8\u30e9\u30af\u30c8\u304c\u81ea\u52d5\u7684\u306b\u30c7\u30fc\u30bf\u306b\u30de\u30c3\u30d7\u3055\u308c\u308b\u306e\u3067\u3001\u30b3\u30f3\u30c8\u30e9\u30af\u30c8\u306e\u5024\u3092\u4f7f\u3063\u3066\u30c7\u30fc\u30bf\u3092\u66f4\u65b0\u3059\u308b\u64cd\u4f5c\u3092\u4f5c\u6210\u3057\u307e\u3059\u3002
poolBdmTips=\u6700\u521d\u306b<a>\u30d3\u30b8\u30cd\u30b9\u5909\u6570</a>\u3001\u304a\u3088\u3073/\u307e\u305f\u306f<a>\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8</a>\u3092\u5b9a\u7fa9\u3057\u3001\u300c\u30c7\u30fc\u30bf\u304b\u3089\u8ffd\u52a0...\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002\n\u5165\u529b\u30b3\u30f3\u30c8\u30e9\u30af\u30c8\u304c\u81ea\u52d5\u7684\u306b\u30c7\u30fc\u30bf\u306b\u30de\u30c3\u30d7\u3055\u308c\u308b\u306e\u3067\u3001\u30b3\u30f3\u30c8\u30e9\u30af\u30c8\u306e\u5024\u3092\u4f7f\u3063\u3066\u30c7\u30fc\u30bf\u3092\u521d\u671f\u5316\u3057\u307e\u3059\u3002
creatingNewForm=Creating new form...
createDataFromContractChoice=Create data from contract
editDataFromContractChoice=Edit an existing data using contract and context when generating a Form from the contract
lazyFieldInAMultipleParentRelationHasBeenDeselect=%s.%s has been unselected. Generating an edition form for this field is not supported (lazy reference in a multiple parent).
aChildHasBeenUnselected=A child relation has been unselected.
moreInfoFormGenerationLink=More information about <a>Contract and Form generation</a>.
......@@ -99,4 +99,9 @@ saving=Saving...
taskBdmTips=You can first define <a>business variables</a> and/or <a>documents</a>, and then click on "Add from data...".\nIt will automatically map contract inputs to data, and create operations to update data with contract values.
poolBdmTips=You can first define <a>business variables</a> and/or <a>documents</a>, and then click on "Add from data...".\nIt will automatically map contract inputs to data, and initialize data with contract values.
creatingNewForm=Creating new form...
createDataFromContractChoice=Create data from contract
editDataFromContractChoice=Edit an existing data using contract and context when generating a Form from the contract
lazyFieldInAMultipleParentRelationHasBeenDeselect=%s.%s has been unselected. Generating an edition form for this field is not supported (lazy reference in a multiple parent).
aChildHasBeenUnselected=A child relation has been unselected.
moreInfoFormGenerationLink=More information about <a>Contract and Form generation</a>.
......@@ -16,6 +16,7 @@ package org.bonitasoft.studio.contract.core.mapping;
import static org.assertj.core.api.Assertions.assertThat;
import static org.bonitasoft.studio.model.businessObject.BusinessObjectBuilder.aBO;
import static org.bonitasoft.studio.model.businessObject.FieldBuilder.aRelationField;
import static org.bonitasoft.studio.model.businessObject.FieldBuilder.aStringField;
import static org.bonitasoft.studio.model.process.builders.PoolBuilder.aPool;
import static org.bonitasoft.studio.model.process.builders.TaskBuilder.aTask;
......@@ -278,4 +279,66 @@ public class FieldToContractInputMappingFactoryTest {
.containsExactly("name");
}
@Test
public void should_create_a_persistenceId_mapping_for_deep_multiple_objects_on_tasks() {
BusinessObject root = aBO("Root").withField(aStringField("rootName").build()).build();
BusinessObject node = aBO("Node").withField(aStringField("nodeName").build()).build();
BusinessObject leaf = aBO("Leaf").withField(aStringField("leafName").build()).build();
RelationField nodeField = aRelationField().withName("node").composition().referencing(node).build();
RelationField leafField = aRelationField().withName("leaf").composition().multiple().referencing(leaf).build();
root.addField(nodeField);
node.addField(leafField);
BusinessObjectData businessObjectData = new BusinessObjectDataBuilder()
.multiple()
.withClassname(root.getQualifiedName()).build();
BusinessObjectModelRepositoryStore<BusinessObjectModelFileStore> repositoryStore = mock(
BusinessObjectModelRepositoryStore.class);
when(repositoryStore.getBusinessObjectByQualifiedName(businessObjectData.getClassName()))
.thenReturn(Optional.of(root));
FieldToContractInputMappingFactory factory = new FieldToContractInputMappingFactory(repositoryStore);
// On a pool
List<FieldToContractInputMapping> mappings = factory.createMappingForBusinessObjectType(aPool().build(),
businessObjectData);
assertThat(mappings).extracting(FieldToContractInputMapping::getField)
.extracting(Field::getName)
.containsExactlyInAnyOrder("rootName", "node");
assertThat(mappings)
.filteredOn(RelationFieldToContractInputMapping.class::isInstance)
.flatExtracting(FieldToContractInputMapping::getChildren)
.extracting(FieldToContractInputMapping::getField)
.extracting(Field::getName)
.containsExactlyInAnyOrder("nodeName", "leaf");
assertThat(mappings)
.filteredOn(RelationFieldToContractInputMapping.class::isInstance)
.flatExtracting(FieldToContractInputMapping::getChildren)
.filteredOn(RelationFieldToContractInputMapping.class::isInstance)
.flatExtracting(FieldToContractInputMapping::getChildren)
.extracting(FieldToContractInputMapping::getField)
.extracting(Field::getName)
.containsExactlyInAnyOrder("leafName");
// On a task
mappings = factory.createMappingForBusinessObjectType(aTask().build(), businessObjectData);
assertThat(mappings).extracting(FieldToContractInputMapping::getField)
.extracting(Field::getName)
.containsExactlyInAnyOrder("rootName", "node",
FieldToContractInputMappingFactory.PERSISTENCE_ID_STRING_FIELD_NAME);
assertThat(mappings)
.filteredOn(RelationFieldToContractInputMapping.class::isInstance)
.flatExtracting(FieldToContractInputMapping::getChildren)
.extracting(FieldToContractInputMapping::getField)
.extracting(Field::getName)
.containsExactlyInAnyOrder("nodeName", "leaf");
assertThat(mappings)
.filteredOn(RelationFieldToContractInputMapping.class::isInstance)
.flatExtracting(FieldToContractInputMapping::getChildren)
.filteredOn(RelationFieldToContractInputMapping.class::isInstance)
.flatExtracting(FieldToContractInputMapping::getChildren)
.extracting(FieldToContractInputMapping::getField)
.extracting(Field::getName)
.containsExactlyInAnyOrder("leafName", FieldToContractInputMappingFactory.PERSISTENCE_ID_STRING_FIELD_NAME);
}
}
......@@ -583,4 +583,114 @@ public class FieldToContractInputMappingExpressionBuilderTest {
+ "}\n"
+ "return nodeList");
}
@Test
public void should_create_expression_for_multiple_business_data_with_two_composition_layers() throws Exception {
RelationField rootField = RelationFieldBuilder.aRelationField()
.composition()
.withName("rootInput")
.multiple()
.referencing(new BusinessObjectBuilder("com.company.Root").build())
.build();
RelationField nodeField = RelationFieldBuilder.aRelationField()
.composition()
.withName("node")
.referencing(new BusinessObjectBuilder("com.company.Node").build())
.build();
RelationField leafField = RelationFieldBuilder.aRelationField()
.composition()
.withName("leaf")
.multiple()
.referencing(new BusinessObjectBuilder("com.company.Leaf").build())
.build();
SimpleField rootNameField = SimpleFieldBuilder.aStringField("rootName").build();
SimpleField nodeNameField = SimpleFieldBuilder.aStringField("nodeName").build();
SimpleField leafNameField = SimpleFieldBuilder.aStringField("leafName").build();
SimpleField persistenceIdRootField = SimpleFieldBuilder.aStringField("persistenceId_string").build();
SimpleField persistenceIdLeafField = SimpleFieldBuilder.aStringField("persistenceId_string").build();
RelationFieldToContractInputMapping rootMapping = new RelationFieldToContractInputMapping(rootField);
RelationFieldToContractInputMapping nodeMapping = new RelationFieldToContractInputMapping(nodeField);
RelationFieldToContractInputMapping leafMapping = new RelationFieldToContractInputMapping(leafField);
SimpleFieldToContractInputMapping rootNameMapping = new SimpleFieldToContractInputMapping(rootNameField);
SimpleFieldToContractInputMapping nodeNameMapping = new SimpleFieldToContractInputMapping(nodeNameField);
SimpleFieldToContractInputMapping leafNameMapping = new SimpleFieldToContractInputMapping(leafNameField);
SimpleFieldToContractInputMapping persistenceIdRootMapping = new SimpleFieldToContractInputMapping(
persistenceIdRootField);
SimpleFieldToContractInputMapping persistenceIdLeafMapping = new SimpleFieldToContractInputMapping(
persistenceIdLeafField);
leafMapping.addChild(leafNameMapping);
leafMapping.addChild(persistenceIdLeafMapping);
nodeMapping.addChild(nodeNameMapping);
nodeMapping.addChild(leafMapping);
rootMapping.addChild(rootNameMapping);
rootMapping.addChild(nodeMapping);
rootMapping.addChild(persistenceIdRootMapping);
BusinessObjectData businessData = aBusinessData().withName("myRoot").build();
FieldToContractInputMappingExpressionBuilder expressionBuilder = newExpressionBuilder();
// On a pool
Expression expression = expressionBuilder.toExpression(businessData, rootMapping, true);
assertThat(expression.getContent()).isEqualToIgnoringWhitespace("def rootList = []\n" +
"//For each item collected in multiple input\n" +
"rootInput.each{\n" +
" //Add a new composed Root instance\n" +
" rootList.add({ currentRootInput ->\n" +
" def rootVar = new com.company.Root()\n" +
" rootVar.rootName = currentRootInput.rootName\n" +
" rootVar.node = {\n" +
" def nodeVar = new com.company.Node()\n" +
" nodeVar.nodeName = currentRootInput.node.nodeName\n" +
" nodeVar.leaf = {\n" +
" def leafList = []\n" +
" //For each item collected in multiple input\n" +
" currentRootInput.node.leaf.each{\n" +
" //Add a new composed Leaf instance\n" +
" leafList.add({ currentLeafInput ->\n" +
" def leafVar = new com.company.Leaf()\n" +
" leafVar.leafName = currentLeafInput.leafName\n" +
" return leafVar\n" +
" }(it))\n" +
" }\n" +
" return leafList}()\n" +
" return nodeVar}()\n" +
" return rootVar\n" +
" }(it))\n" +
"}\n" +
"return rootList");
// On a task
expression = expressionBuilder.toExpression(businessData, rootMapping, false);
assertThat(expression.getContent()).isEqualToIgnoringWhitespace("def rootList = []\n" +
"//For each item collected in multiple input\n" +
"rootInput.each{\n" +
" //Add Root instance\n" +
" rootList.add({ currentRootInput ->\n" +
" def rootVar = myRoot.find { it.persistenceId.toString() == currentRootInput.persistenceId_string} ?: new com.company.Root()\n"
+
" rootVar.rootName = currentRootInput.rootName\n" +
" rootVar.node = {\n" +
" def nodeVar = rootVar.node ?: new com.company.Node()\n" +
" nodeVar.nodeName = currentRootInput.node.nodeName\n" +
" nodeVar.leaf = {\n" +
" def leafList = []\n" +
" //For each item collected in multiple input\n" +
" currentRootInput.node.leaf.each{\n" +
" //Add a new composed Leaf instance\n" +
" leafList.add({ currentLeafInput ->\n" +
" def leafVar = nodeVar.leaf?.find { it.persistenceId.toString() == currentLeafInput.persistenceId_string } ?: new com.company.Leaf()\n"
+
" leafVar.leafName = currentLeafInput.leafName\n" +
" return leafVar\n" +
" }(it))\n" +
" }\n" +
" return leafList}()\n" +
" return nodeVar}()\n" +
" return rootVar\n" +
" }(it))\n" +
"}\n" +
"return rootList");
}
}
......@@ -18,6 +18,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.bonitasoft.studio.model.process.builders.BusinessObjectDataBuilder.aBusinessData;
import static org.bonitasoft.studio.model.process.builders.ContractBuilder.aContract;
import static org.bonitasoft.studio.model.process.builders.PoolBuilder.aPool;
import static org.bonitasoft.studio.model.process.builders.TaskBuilder.aTask;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
......@@ -31,11 +32,14 @@ import org.bonitasoft.studio.contract.core.mapping.FieldToContractInputMapping;
import org.bonitasoft.studio.contract.core.mapping.FieldToContractInputMappingFactory;
import org.bonitasoft.studio.contract.core.mapping.RelationFieldToContractInputMapping;
import org.bonitasoft.studio.contract.core.mapping.SimpleFieldToContractInputMapping;
import org.bonitasoft.studio.model.businessObject.FieldBuilder.SimpleFieldBuilder;
import org.bonitasoft.studio.model.process.BusinessObjectData;
import org.bonitasoft.studio.model.process.Contract;
import org.bonitasoft.studio.model.process.Pool;
import org.bonitasoft.studio.swt.rules.RealmWithDisplay;
import org.eclipse.core.databinding.conversion.IConverter;
import org.eclipse.core.databinding.observable.list.WritableList;
import org.eclipse.core.databinding.observable.set.IObservableSet;
import org.eclipse.core.databinding.observable.set.WritableSet;
import org.eclipse.core.databinding.observable.value.WritableValue;
import org.eclipse.swt.events.SelectionAdapter;
......@@ -228,4 +232,36 @@ public class CreateContractInputFromBusinessObjectWizardPageTest {
assertThat(checkedElements.contains(childMappingMandatory)).isTrue();
}
@Test
public void should_always_keep_persistence_id_fields_generated() {
CreateContractInputFromBusinessObjectWizardPage page = new CreateContractInputFromBusinessObjectWizardPage(
aTask().build(),
new GenerationOptions(),
new WritableValue<>(),
mock(FieldToContractInputMappingFactory.class),
new WritableList<>(),
mock(BusinessObjectModelRepositoryStore.class));
SimpleField rootNameField = SimpleFieldBuilder.aStringField("rootName").build();
SimpleField persistenceIdRootField = SimpleFieldBuilder.aStringField("persistenceId_string").build();
SimpleFieldToContractInputMapping rootNameMapping = new SimpleFieldToContractInputMapping(rootNameField);
SimpleFieldToContractInputMapping rootPersistenceIdMapping = new SimpleFieldToContractInputMapping(
persistenceIdRootField);
page.setMappings(Lists.newArrayList(rootNameMapping, rootPersistenceIdMapping));
IObservableSet<FieldToContractInputMapping> checkedElements = new WritableSet<>();
IConverter converter = page.createMappingsToCheckedElementsConverter(new WritableValue());
converter.convert(checkedElements);
assertThat(rootNameMapping.isGenerated()).isFalse();
assertThat(rootPersistenceIdMapping.isGenerated()).isTrue();
checkedElements.add(rootNameMapping);
converter.convert(checkedElements);
assertThat(rootNameMapping.isGenerated()).isTrue();
assertThat(rootPersistenceIdMapping.isGenerated()).isTrue();
}
}
......@@ -20,38 +20,41 @@ import java.util.Map;
import org.bonitasoft.engine.bdm.model.field.RelationField;
import org.bonitasoft.studio.contract.i18n.Messages;
import org.bonitasoft.studio.model.process.BusinessObjectData;
import org.eclipse.core.databinding.validation.ValidationStatus;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
public class UnselectLazyReferencesInMultipleContainer {
private Map<FieldToContractInputMapping, IStatus> statuses = new HashMap<FieldToContractInputMapping, IStatus>();
private Map<FieldToContractInputMapping, IStatus> statuses = new HashMap<>();
public void apply(List<FieldToContractInputMapping> mappings, boolean multipleData) {
public void apply(List<FieldToContractInputMapping> mappings, BusinessObjectData data) {
statuses.clear();
updateGeneratedMappings(mappings, multipleData);
updateGeneratedMappings(mappings, data);
}
private void updateGeneratedMappings(List<FieldToContractInputMapping> mappings, boolean multipleData) {
private void updateGeneratedMappings(List<FieldToContractInputMapping> mappings, BusinessObjectData data) {
for (FieldToContractInputMapping mapping : mappings) {
if (mapping.getField() instanceof RelationField
&& ((RelationField) mapping.getField()).isLazy()
&& (multipleData || hasAMultipleParent(mapping))) {
&& (data.isMultiple() || hasAMultipleParent(mapping))) {
mapping.setGenerated(false);
String name = mapping.getParent() != null
? ((RelationField) mapping.getParent().getField()).getReference().getSimpleName()
: data.getName();
statuses.put(mapping,
ValidationStatus
.warning(String.format(Messages.lazyFieldInAMultipleParentRelationHasBeenDeselect,
((RelationField) mapping.getParent().getField()).getReference().getSimpleName(),
mapping.getField().getName())));
name, mapping.getField().getName())));
FieldToContractInputMapping parent = mapping.getParent();
while (parent != null) {
statuses.put(parent,ValidationStatus.warning(Messages.aChildHasBeenUnselected));
statuses.put(parent, ValidationStatus.warning(Messages.aChildHasBeenUnselected));
parent = parent.getParent();
}
unselect(mapping.getChildren());
}else {
updateGeneratedMappings(mapping.getChildren(), multipleData);
} else {
updateGeneratedMappings(mapping.getChildren(), data);
}
}
}
......@@ -72,7 +75,7 @@ public class UnselectLazyReferencesInMultipleContainer {
}
public IStatus getStatus(FieldToContractInputMapping mapping) {
return statuses.getOrDefault(mapping,Status.OK_STATUS);
return statuses.getOrDefault(mapping, Status.OK_STATUS);
}
}
......@@ -23,7 +23,6 @@ import java.util.Collections;
import java.util.List;
import java.util.Objects;
import org.bonitasoft.engine.bdm.model.field.Field;
import org.bonitasoft.studio.businessobject.core.repository.BusinessObjectModelFileStore;
import org.bonitasoft.studio.businessobject.core.repository.BusinessObjectModelRepositoryStore;
import org.bonitasoft.studio.common.ProductVersion;
......@@ -59,7 +58,6 @@ import org.eclipse.core.databinding.observable.value.IValueChangeListener;
import org.eclipse.core.databinding.observable.value.SelectObservableValue;
import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
import org.eclipse.core.databinding.observable.value.WritableValue;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.databinding.EMFDataBindingContext;
import org.eclipse.emf.databinding.EMFObservables;
import org.eclipse.jface.databinding.swt.WidgetProperties;
......@@ -167,7 +165,7 @@ public class CreateContractInputFromBusinessObjectWizardPage extends WizardPage
BonitaStudioLog.error(e);
}
}
private void createReminderText(final EMFDataBindingContext dbc, final Composite composite) {
final CLabel reminder = new CLabel(composite, SWT.NONE);
final Display d = Display.getCurrent();
......@@ -176,7 +174,7 @@ public class CreateContractInputFromBusinessObjectWizardPage extends WizardPage
reminder.setLayoutData(GridDataFactory.fillDefaults().hint(600, SWT.DEFAULT).create());
final Button autoGeneratedOperationButton = new Button(composite, SWT.RADIO);
final Button manuallyDefinedOperationButton = new Button(composite, SWT.RADIO);
actionObservable = new SelectObservableValue<Boolean>(Boolean.class);
actionObservable = new SelectObservableValue<>(Boolean.class);
actionObservable.addOption(Boolean.TRUE, WidgetProperties.selection().observe(autoGeneratedOperationButton));
actionObservable.addOption(Boolean.FALSE, WidgetProperties.selection().observe(manuallyDefinedOperationButton));
if (contract.eContainer() instanceof Task) {
......@@ -270,30 +268,30 @@ public class CreateContractInputFromBusinessObjectWizardPage extends WizardPage
dbc.addValidationStatusProvider(multiValidator);
new Label(viewerComposite, SWT.NONE); //FILLER
Link formGenerationDocLink = new Link(viewerComposite,SWT.NONE);
Link formGenerationDocLink = new Link(viewerComposite, SWT.NONE);
formGenerationDocLink.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create());
formGenerationDocLink.setText(Messages.moreInfoFormGenerationLink);
formGenerationDocLink.addListener(SWT.Selection, event -> openBrowser(FORM_GENERATION_REDIRECT_ID));
ColumnViewerToolTipSupport.enableFor(treeViewer);
}
protected Converter createMappingsToCheckedElementsConverter(final WritableValue mappingsObservableValue) {
return new Converter(IObservableSet.class, WritableList.class) {
@Override
public Object convert(final Object fromObject) {
if (fromObject != null) {
final IObservableSet set = (IObservableSet) fromObject;
for (final FieldToContractInputMapping mapping : mappings) {
mapping.setGenerated(set.contains(mapping));
protected IConverter createMappingsToCheckedElementsConverter(WritableValue mappingsObservableValue) {
return ConverterBuilder.<IObservableSet, WritableValue> newConverter()
.fromType(IObservableSet.class)
.toType(WritableValue.class)
.withConvertFunction(set -> {
if (set != null) {
for (FieldToContractInputMapping mapping : mappings) {
boolean generated = set.contains(mapping) || Objects.equals(mapping.getField().getName(),
FieldToContractInputMappingFactory.PERSISTENCE_ID_STRING_FIELD_NAME);
mapping.setGenerated(generated);
}
return mappingsObservableValue;
}
return mappingsObservableValue;
}
return new WritableList<>();
}
};
return new WritableValue<>();
}).create();
}
protected Converter createCheckedElementsToMappingsConverter(final IObservableSet checkedElements) {
......@@ -427,8 +425,8 @@ public class CreateContractInputFromBusinessObjectWizardPage extends WizardPage
private void createMapping(BusinessObjectData data) {
mappings = fieldToContractInputMappingFactory.createMappingForBusinessObjectType(contractContainer, data);
if (generationOptions.getEditMode() == EditMode.EDIT) {
lazyFieldStatusProvider.apply(mappings, data.isMultiple());
}else if(generationOptions.getEditMode() == EditMode.CREATE) {
lazyFieldStatusProvider.apply(mappings, data);
} else if (generationOptions.getEditMode() == EditMode.CREATE) {
new RemoveAggregateReferencesChildren().apply(mappings);
}
fieldToContractInputMappingsObservable.clear();
......
......@@ -43,7 +43,7 @@ public class BonitaGroovyConfiguration extends GroovyConfiguration {
private static final Set<String> ALLOWED_CATEGORIES = new HashSet<>();
static {
ALLOWED_CATEGORIES.add("org.codehaus.groovy.eclipse.codeassist.category");
ALLOWED_CATEGORIES.add("org.bonitasoft.groovy.codeassist.category");
ALLOWED_CATEGORIES.add("org.codehaus.groovy.eclipse.codeassist.templates.category");
}
......
......@@ -34,5 +34,33 @@
class="org.bonitasoft.studio.groovy.provider.GroovyProjectListenerProvider">
</projectListenerProvider>
</extension>
<extension
id="org.bonitasoft.studio.groovy.completionComputer"
name="Groovy Code Completions"
point="org.eclipse.jdt.ui.javaCompletionProposalComputer">
<javaCompletionProposalComputer
activate="true"
categoryId="org.bonitasoft.groovy.codeassist.category"
class="org.bonitasoft.studio.groovy.contentassist.CustomGroovyCompletionProposalComputer"
needsSortingAfterFiltering="true">
<partition
type="__dftl_partition_content_type">
</partition>
<partition
type="__java_string">
</partition>
<!-- this is not an error; pde does not recognize this as a valid partition type -->
<partition
type="__groovy_multiline_string">
</partition>
</javaCompletionProposalComputer>
</extension>
<extension
id="org.bonitasoft.groovy.codeassist.category"
name="Groovy Proposals"
point="org.eclipse.jdt.ui.javaCompletionProposalComputer">
<proposalCategory
icon="icons/groovy.png"></proposalCategory>
</extension>
</plugin>
/**
*
*/
package org.bonitasoft.studio.groovy.contentassist;
import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.ast.Variable;
import org.codehaus.groovy.ast.expr.VariableExpression;
import org.codehaus.groovy.eclipse.codeassist.DocumentSourceBuffer;
import org.codehaus.groovy.eclipse.codeassist.requestor.CompletionNodeFinder;
import org.codehaus.groovy.eclipse.codeassist.requestor.ContentAssistContext;
import org.codehaus.groovy.eclipse.codeassist.requestor.GroovyCompletionProposalComputer;
import org.codehaus.groovy.eclipse.core.ISourceBuffer;
import org.codehaus.groovy.eclipse.core.util.ExpressionFinder;
import org.codehaus.jdt.groovy.model.GroovyCompilationUnit;
import org.eclipse.jface.text.IDocument;
public class CustomGroovyCompletionProposalComputer extends GroovyCompletionProposalComputer {
@Override
public ContentAssistContext createContentAssistContext(GroovyCompilationUnit gunit, int invocationOffset,
IDocument document) {
String fullCompletionText = findCompletionText(document, invocationOffset);
String[] completionExpressions = findCompletionExpression(fullCompletionText);
final String completionExpression;
if (completionExpressions == null || "@".equals(fullCompletionText)) {
completionExpression = "";
} else if (completionExpressions[1] == null) {
completionExpression = completionExpressions[0];
} else {
completionExpression = completionExpressions[1];
}
int completionEnd = findCompletionEnd(document, invocationOffset);
int supportingNodeEnd = findSupportingNodeEnd(gunit, invocationOffset, fullCompletionText);
CompletionNodeFinder finder = new CompletionNodeFinder(invocationOffset, completionEnd, supportingNodeEnd,
completionExpression, fullCompletionText);
ContentAssistContext context = finder.findContentAssistContext(gunit);
ASTNode node = context.completionNode;
if(node instanceof VariableExpression) {
Variable declaredVariable = gunit.getModuleNode().getStatementBlock().getVariableScope().getDeclaredVariable(((VariableExpression) node).getName());
if(declaredVariable !=null ) {
((VariableExpression) node).setAccessedVariable(declaredVariable);
}
}
return context;
}
private String[] findCompletionExpression(String completionText) {
return new ExpressionFinder().splitForCompletion(completionText);
}
private int findCompletionEnd(IDocument doc, int offset) {
ISourceBuffer buffer = new DocumentSourceBuffer(doc);
return new ExpressionFinder().findTokenEnd(buffer, offset);
}
}
......@@ -12,10 +12,10 @@ import java.util.ArrayList;
import java.util.List;
import org.bonitasoft.studio.common.log.BonitaStudioLog;
import org.bonitasoft.studio.common.repository.JavaProjectClassLoader;
import org.bonitasoft.studio.groovy.ScriptVariable;
import org.bonitasoft.studio.model.expression.Expression;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.CompileUnit;
import org.codehaus.groovy.ast.VariableScope;
import org.codehaus.groovy.ast.expr.VariableExpression;
import org.codehaus.jdt.groovy.model.GroovyCompilationUnit;
......@@ -29,108 +29,108 @@ import org.eclipse.ui.IEditorPart;
public class ExtendedJavaContentAssistInvocationContext extends JavaContentAssistInvocationContext {
private boolean fCUComputed = false;
private List<Expression> variableScope;
private Document tmpDocument;
private int offset;
public static final String BONITA_KEYWORDS_DATA_KEY = "bonita.keywords";
public static final String PROCESS_VARIABLES_DATA_KEY = "process.variables";
public ExtendedJavaContentAssistInvocationContext(final ITextViewer viewer, final int offset, final IEditorPart editor) {
super(viewer, offset, editor);
}
public ExtendedJavaContentAssistInvocationContext(IEditorPart editor,
ITextViewer viewer,
int offset,
Document tmpDocument,
int tmpOffset,
List<Expression> variableScope) {
super(viewer, tmpOffset, editor);
this.offset = offset;
this.variableScope = variableScope;
this.tmpDocument = tmpDocument;
}
public List<Expression> getVariableScope() {
return variableScope;
}
/*
* (non-Javadoc)
* @see org.eclipse.jdt.ui.text.java.ContentAssistInvocationContext#getDocument()
*/
@Override
public IDocument getDocument() {
if (tmpDocument != null) {
return tmpDocument;
}
return super.getDocument();
}
public int getOffset() {
return offset;
}
@Override
public ICompilationUnit getCompilationUnit() {
if (!fCUComputed) {
final GroovyCompilationUnit compilationUnit = (GroovyCompilationUnit) super.getCompilationUnit();
final ITextViewer viewer = getViewer();
List<ScriptVariable> processVariables = new ArrayList<>();
List<ScriptVariable> providedVariables = new ArrayList<>();
if (viewer != null) {
processVariables = (List<ScriptVariable>) viewer.getTextWidget().getData(PROCESS_VARIABLES_DATA_KEY);
providedVariables = (List<ScriptVariable>) viewer.getTextWidget().getData(BONITA_KEYWORDS_DATA_KEY);
}
final VariableScope vScope = compilationUnit.getModuleNode().getStatementBlock().getVariableScope();
final IJavaProject javaProject = compilationUnit.getJavaProject();
final JavaProjectClassLoader classLoader = new JavaProjectClassLoader(javaProject);
if (processVariables != null) {
for (final ScriptVariable scriptVariable : processVariables) {
try {
addToScope(classLoader, vScope, scriptVariable);
} catch (final ClassNotFoundException e) {
BonitaStudioLog.error(e);
}
}
}
if (providedVariables != null) {
for (final ScriptVariable scriptVariable : providedVariables) {
try {
addToScope(classLoader, vScope, scriptVariable);
} catch (final ClassNotFoundException e) {
BonitaStudioLog.error(e);
}
}
}
if (variableScope != null) {
for (final Expression expression : variableScope) {
try {
addToScope(classLoader, vScope, new ScriptVariable(expression.getName(), expression.getReturnType()));
} catch (final ClassNotFoundException e) {
BonitaStudioLog.error(e);
}
}
}
fCUComputed = true;
return compilationUnit;
}
return super.getCompilationUnit();
}
private void addToScope(final ClassLoader classloader, final VariableScope variableScope, final ScriptVariable scriptVariable)
throws ClassNotFoundException {
final ClassNode classNode = new ClassNode(classloader.loadClass(scriptVariable.getType()));
final VariableExpression variableExpression = new VariableExpression(scriptVariable.getName(), classNode);
variableExpression.setEnd(-1);
variableScope.putDeclaredVariable(variableExpression);
}
private boolean fCUComputed = false;
private List<Expression> variableScope;
private Document tmpDocument;
private int offset;
public static final String BONITA_KEYWORDS_DATA_KEY = "bonita.keywords";
public static final String PROCESS_VARIABLES_DATA_KEY = "process.variables";
public ExtendedJavaContentAssistInvocationContext(final ITextViewer viewer, final int offset,
final IEditorPart editor) {
super(viewer, offset, editor);
}
public ExtendedJavaContentAssistInvocationContext(IEditorPart editor, ITextViewer viewer, int offset,
Document tmpDocument, int tmpOffset, List<Expression> variableScope) {
super(viewer, tmpOffset, editor);
this.offset = offset;
this.variableScope = variableScope;
this.tmpDocument = tmpDocument;
}
public List<Expression> getVariableScope() {
return variableScope;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.jdt.ui.text.java.ContentAssistInvocationContext#getDocument()
*/
@Override
public IDocument getDocument() {
if (tmpDocument != null) {
return tmpDocument;
}
return super.getDocument();
}
public int getOffset() {
return offset;
}
@Override
public ICompilationUnit getCompilationUnit() {
if (!fCUComputed) {
final GroovyCompilationUnit compilationUnit = (GroovyCompilationUnit) super.getCompilationUnit();
final ITextViewer viewer = getViewer();
List<ScriptVariable> processVariables = new ArrayList<>();
List<ScriptVariable> providedVariables = new ArrayList<>();
if (viewer != null) {
processVariables = (List<ScriptVariable>) viewer.getTextWidget().getData(PROCESS_VARIABLES_DATA_KEY);
providedVariables = (List<ScriptVariable>) viewer.getTextWidget().getData(BONITA_KEYWORDS_DATA_KEY);
}
final IJavaProject javaProject = compilationUnit.getJavaProject();
if (processVariables != null) {
for (final ScriptVariable scriptVariable : processVariables) {
try {
addToScope(compilationUnit, scriptVariable);
} catch (final ClassNotFoundException e) {
BonitaStudioLog.error(e);
}
}
}
if (providedVariables != null) {
for (final ScriptVariable scriptVariable : providedVariables) {
try {
addToScope(compilationUnit, scriptVariable);
} catch (final ClassNotFoundException e) {
BonitaStudioLog.error(e);
}
}
}
if (variableScope != null) {
for (final Expression expression : variableScope) {
try {
addToScope(compilationUnit,
new ScriptVariable(expression.getName(), expression.getReturnType()));
} catch (final ClassNotFoundException e) {
BonitaStudioLog.error(e);
}
}
}
fCUComputed = true;
return compilationUnit;
}
return super.getCompilationUnit();
}
private void addToScope(final GroovyCompilationUnit compilationUnit, final ScriptVariable scriptVariable)
throws ClassNotFoundException {
CompileUnit cu = compilationUnit.getModuleNode().getUnit();
ClassNode classNode = new ClassNode(cu.getClassLoader().loadClass(scriptVariable.getType()));
final VariableExpression variableExpression = new VariableExpression(scriptVariable.getName(), classNode);
variableExpression.setEnd(-1);
final VariableScope vScope = compilationUnit.getModuleNode().getStatementBlock().getVariableScope();
vScope.putDeclaredVariable(variableExpression);
}
}
......@@ -155,7 +155,7 @@ import org.junit.runners.Suite;
BPMNConnectorExportImportTest.class,
BPMNGatewayExportImportTest.class,
BPMNEventSubProcessExportImportTest.class,
OrganizationCreationTest.class,
OrganizationCreationTest.class
})
public class SWTBotTestSuite {
......
......@@ -71,7 +71,6 @@ public class ContractIT {
final ContractContainer contractContainer = (ContractContainer) activeProcessDiagramEditor
.getSelectedSemanticElement();
createExpenseReport(botProcessDiagramPerspective, contractContainer);
}
protected void createExpenseReport(final BotProcessDiagramPerspective botProcessDiagramPerspective,
......