Commit ae8799d8 authored by Romain Bioteau's avatar Romain Bioteau

BS-6760

Clean jar dependencies if connector/actor implementation provide sources
parent f52af5c9
......@@ -45,7 +45,10 @@ Require-Bundle: org.eclipse.core.runtime,
org.bonitasoft.studio.diagram.custom,
org.eclipse.emf.compare;bundle-version="1.2.2",
org.eclipse.emf.compare.diff;bundle-version="1.2.2",
org.eclipse.emf.compare.match
org.eclipse.emf.compare.match,
org.junit;bundle-version="4.11.0";resolution:=optional,
org.mockito;bundle-version="1.9.5";resolution:=optional,
assertj-core;bundle-version="1.5.0";resolution:=optional
Bundle-ActivationPolicy: lazy
Import-Package: org.bonitasoft.engine.api,
org.bonitasoft.engine.bpm,
......
/**
* Copyright (C) 2014 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.operation;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;
import org.eclipse.core.resources.IResource;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
/**
* @author Romain Bioteau
*
*/
@RunWith(MockitoJUnitRunner.class)
public class ImportFolderComparatorTest {
private ImportFolderComparator comparator;
@Mock
private IResource diagramResource;
@Mock
private IResource otherResource;
@Mock
private IResource libResource;
@Mock
private IResource srcResource;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
comparator = new ImportFolderComparator();
when(diagramResource.getName()).thenReturn("diagrams");
when(otherResource.getName()).thenReturn("other");
when(libResource.getName()).thenReturn("lib");
when(srcResource.getName()).thenReturn("src-filter");
}
/**
* @throws java.lang.Exception
*/
@After
public void tearDown() throws Exception {
}
@Test
public void shoud_diagram_folder_be_in_first_position() throws Exception {
assertThat(comparator.compare(diagramResource, otherResource)).isEqualTo(-1);
assertThat(comparator.compare(otherResource, diagramResource)).isEqualTo(1);
assertThat(comparator.compare(diagramResource, libResource)).isEqualTo(-1);
assertThat(comparator.compare(libResource, diagramResource)).isEqualTo(1);
assertThat(comparator.compare(diagramResource, srcResource)).isEqualTo(-1);
assertThat(comparator.compare(srcResource, diagramResource)).isEqualTo(1);
}
@Test
public void shoud_lib_folder_be_in_second_position() throws Exception {
assertThat(comparator.compare(libResource, otherResource)).isEqualTo(-1);
assertThat(comparator.compare(otherResource, libResource)).isEqualTo(1);
assertThat(comparator.compare(diagramResource, libResource)).isEqualTo(-1);
assertThat(comparator.compare(libResource, diagramResource)).isEqualTo(1);
assertThat(comparator.compare(libResource, srcResource)).isEqualTo(-1);
assertThat(comparator.compare(srcResource, libResource)).isEqualTo(1);
}
@Test
public void shoud_folder_containg_src_be_in_third_position() throws Exception {
assertThat(comparator.compare(srcResource, otherResource)).isEqualTo(-1);
assertThat(comparator.compare(otherResource, srcResource)).isEqualTo(1);
assertThat(comparator.compare(diagramResource, srcResource)).isEqualTo(-1);
assertThat(comparator.compare(srcResource, diagramResource)).isEqualTo(1);
assertThat(comparator.compare(libResource, srcResource)).isEqualTo(-1);
assertThat(comparator.compare(srcResource, libResource)).isEqualTo(1);
}
}
......@@ -109,7 +109,7 @@ public class ImportBosArchiveOperation {
final IResource[] folders = rootContainer.members(IContainer.FOLDER);
if (folders != null) {
final List<IResource> folderSortedList = new ArrayList<IResource>(Arrays.asList(folders));
final Comparator<IResource> importFolderComparator = new ImportFolderComparator<IResource>();
final Comparator<IResource> importFolderComparator = new ImportFolderComparator();
Collections.sort(folderSortedList, importFolderComparator);
for (final IResource folder : folderSortedList) {
try {
......
......@@ -5,14 +5,14 @@
* 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
* 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/>.
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.bonitasoft.studio.common.repository.operation;
......@@ -20,25 +20,62 @@ import java.util.Comparator;
import org.eclipse.core.resources.IResource;
/**
* @author Romain Bioteau
* Use to have a deterministic order of the imported repository
* Use to have a deterministic order of the imported repository
*/
public class ImportFolderComparator<T> implements Comparator<IResource> {
public class ImportFolderComparator implements Comparator<IResource> {
private static final String SRC_FOLDER_NAME = "src";
private static final String LIB_FOLDER_NAME = "lib";
/* (non-Javadoc)
private static final String DIAGRAMS_FOLDER_NAME = "diagrams";
/*
* (non-Javadoc)
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
@Override
public int compare(IResource res0, IResource res1) {
if(res0.getName().equals("diagrams")){ //We want to have the diagrams imported first
String firstResourceName = res0.getName();
String secondResourceName = res1.getName();
if (firstResourceName.equals(DIAGRAMS_FOLDER_NAME)) { // diagram folder first
return -1;
}
if(res1.getName().equals("diagrams")){
if (secondResourceName.equals(DIAGRAMS_FOLDER_NAME)) {
return 1;
}
if (firstResourceName.equals(LIB_FOLDER_NAME)) { // Then lib folder
if (secondResourceName.equals(DIAGRAMS_FOLDER_NAME)) {
return 1;
} else {
return -1;
}
}
if (secondResourceName.equals(LIB_FOLDER_NAME)) {
if (firstResourceName.equals(DIAGRAMS_FOLDER_NAME)) {
return -1;
} else {
return 1;
}
}
if (firstResourceName.contains(SRC_FOLDER_NAME)) { // Then all src folder
if (secondResourceName.equals(DIAGRAMS_FOLDER_NAME) || secondResourceName.equals(LIB_FOLDER_NAME)) {
return 1;
} else {
return -1;
}
}
if (secondResourceName.contains(SRC_FOLDER_NAME)) {
if (firstResourceName.equals(DIAGRAMS_FOLDER_NAME) || firstResourceName.equals(LIB_FOLDER_NAME)) {
return -1;
} else {
return 1;
}
}
return 0;
}
}
......@@ -5,32 +5,33 @@
* 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
* 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/>.
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.bonitasoft.studio.common.repository.store;
import java.util.Comparator;
import org.bonitasoft.studio.common.repository.model.IRepositoryFileStore;
import org.bonitasoft.studio.common.repository.model.IRepositoryStore;
/**
* @author Romain Bioteau
*
*
*/
public class RepositoryStoreComparator implements Comparator<IRepositoryStore> {
public class RepositoryStoreComparator implements Comparator<IRepositoryStore<? extends IRepositoryFileStore>> {
@Override
public int compare(IRepositoryStore f1, IRepositoryStore f2) {
String f1Name = f1.getDisplayName() == null ? f1.getName() : f1.getDisplayName() ;
String f2Name = f2.getDisplayName() == null ? f2.getName() : f2.getDisplayName() ;
return f1Name.compareTo(f2Name);
}
@Override
public int compare(IRepositoryStore<? extends IRepositoryFileStore> f1, IRepositoryStore<? extends IRepositoryFileStore> f2) {
String f1Name = f1.getDisplayName() == null ? f1.getName() : f1.getDisplayName();
String f2Name = f2.getDisplayName() == null ? f2.getName() : f2.getDisplayName();
return f1Name.compareTo(f2Name);
}
}
/**
* Copyright (C) 2014 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.store;
import org.eclipse.jdt.core.search.TypeNameRequestor;
/**
* @author Romain Bioteau
*
*/
public class TypeNameFoundRequestor extends TypeNameRequestor {
private boolean found;
@Override
public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path) {
found = true;
}
public boolean isFound() {
return found;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="src-test/java"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="output" path="bin"/>
......
......@@ -40,5 +40,9 @@ Require-Bundle: org.eclipse.core.runtime,
org.bonitasoft.studio.dependencies;bundle-version="1.0.0",
org.bonitasoft.studio.expression.editor;bundle-version="1.0.0",
org.eclipse.ui.ide;bundle-version="3.7.0",
org.bonitasoft.studio.scripting;bundle-version="1.0.0"
org.bonitasoft.studio.scripting;bundle-version="1.0.0",
org.junit;bundle-version="4.11.0";resolution:=optional,
org.mockito;bundle-version="1.9.5";resolution:=optional,
assertj-core;bundle-version="1.5.0";resolution:=optional,
org.powermock;bundle-version="1.5.2";resolution:=optional
Bundle-ActivationPolicy: lazy
......@@ -9,3 +9,4 @@ bin.includes = .,\
jars.compile.order = .
source.. = src/
output.. = bin/
src.excludes = src-test/java/
/**
* Copyright (C) 2014 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.connector.model.implementation;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import org.bonitasoft.studio.common.NamingUtils;
import org.bonitasoft.studio.common.repository.filestore.EMFFileStore;
import org.bonitasoft.studio.common.repository.model.IRepositoryFileStore;
import org.bonitasoft.studio.common.repository.model.IRepositoryStore;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
/**
* @author Romain Bioteau
*
*/
@RunWith(MockitoJUnitRunner.class)
public class AbstractConnectorImplRepositoryStoreTest {
private AbstractConnectorImplRepositoryStore<? extends EMFFileStore> implRepositoryStore;
@Mock
private IRepositoryFileStore fStore;
@Mock
private IRepositoryStore<? extends IRepositoryFileStore> dependencyRepositoryStore;
@Mock
private IRepositoryStore<? extends IRepositoryFileStore> sourceRepositoryStore;
@Mock
private IRepositoryFileStore sourceFileStore;
@Mock
private IRepositoryFileStore depFileStore;
private ConnectorImplementation connectorImpl;
/**
* @throws java.lang.Exception
*/
@SuppressWarnings("unchecked")
@Before
public void setUp() throws Exception {
implRepositoryStore = mock(AbstractConnectorImplRepositoryStore.class);
doAnswer(Answers.CALLS_REAL_METHODS.get()).when(implRepositoryStore)
.cleanJarDependency(any(IRepositoryFileStore.class), any(IRepositoryStore.class), any(IRepositoryStore.class));
connectorImpl = ConnectorImplementationFactory.eINSTANCE.createConnectorImplementation();
connectorImpl.setDefinitionId("def");
connectorImpl.setDefinitionVersion("1.0");
connectorImpl.setImplementationClassname("org.bonita.MyImpl");
connectorImpl.setImplementationId("impl");
connectorImpl.setImplementationVersion("1.0");
JarDependencies deps = ConnectorImplementationFactory.eINSTANCE.createJarDependencies();
String jarName = NamingUtils.toConnectorImplementationFilename(connectorImpl.getImplementationId(), connectorImpl.getImplementationVersion(), false)
+ ".jar";
deps.getJarDependency().add(
jarName);
connectorImpl.setJarDependencies(deps);
doReturn(connectorImpl).when(fStore).getContent();
doReturn(depFileStore).when(dependencyRepositoryStore).getChild(jarName);
}
/**
* @throws java.lang.Exception
*/
@After
public void tearDown() throws Exception {
}
@Test
public void should_cleanJarDependency_remove_jar_from_dependencies_if_impl_has_sources() throws Exception {
doReturn(sourceFileStore).when(sourceRepositoryStore).getChild(connectorImpl.getImplementationClassname());
implRepositoryStore.cleanJarDependency(fStore, dependencyRepositoryStore, sourceRepositoryStore);
verify(depFileStore).delete();
}
@Test
public void should_cleanJarDependency_not_remove_jar_from_dependencies_if_impl_has_no_sources() throws Exception {
doReturn(null).when(sourceRepositoryStore).getChild(connectorImpl.getImplementationClassname());
implRepositoryStore.cleanJarDependency(fStore, dependencyRepositoryStore, sourceRepositoryStore);
verifyZeroInteractions(depFileStore);
}
}
/**
* Copyright (C) 2012 BonitaSoft S.A.
* BonitaSoft, 31 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.connector.model.implementation;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.bonitasoft.studio.common.NamingUtils;
import org.bonitasoft.studio.common.log.BonitaStudioLog;
import org.bonitasoft.studio.common.repository.Repository;
import org.bonitasoft.studio.common.repository.RepositoryManager;
import org.bonitasoft.studio.common.repository.filestore.EMFFileStore;
import org.bonitasoft.studio.common.repository.model.IRepositoryFileStore;
import org.bonitasoft.studio.common.repository.model.IRepositoryStore;
import org.bonitasoft.studio.common.repository.store.AbstractEMFRepositoryStore;
import org.bonitasoft.studio.connector.model.implementation.util.ConnectorImplementationAdapterFactory;
import org.bonitasoft.studio.connector.model.implementation.util.ConnectorImplementationResourceImpl;
import org.bonitasoft.studio.connector.model.implementation.util.ConnectorImplementationXMLProcessor;
import org.bonitasoft.studio.dependencies.repository.DependencyRepositoryStore;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl;
import org.eclipse.emf.edapt.history.Release;
import org.eclipse.emf.edapt.migration.MigrationException;
import org.eclipse.emf.edapt.migration.execution.Migrator;
import org.eclipse.emf.edapt.migration.execution.ValidationLevel;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
/**
* @author Romain Bioteau
*
*/
public abstract class AbstractConnectorImplRepositoryStore<T extends EMFFileStore> extends AbstractEMFRepositoryStore<T> implements IRepositoryStore<T>,
IImplementationRepositoryStore {
@Override
protected void addAdapterFactory(ComposedAdapterFactory adapterFactory) {
adapterFactory.addAdapterFactory(new ConnectorImplementationAdapterFactory());
}
@Override
public ConnectorImplementation getImplementation(String id, String version) {
for (ConnectorImplementation impl : getImplementations()) {
if (impl.getImplementationId().equals(id) && impl.getImplementationVersion().equals(version)) {
return impl;
}
}
return null;
}
@Override
public List<ConnectorImplementation> getImplementations() {
List<ConnectorImplementation> result = new ArrayList<ConnectorImplementation>();
for (IRepositoryFileStore fileStore : getChildren()) {
ConnectorImplementation def = (ConnectorImplementation) fileStore.getContent();
result.add(def);
}
return result;
}
@Override
public List<ConnectorImplementation> getImplementations(String definitionId, String definitionVersion) {
List<ConnectorImplementation> implementations = new ArrayList<ConnectorImplementation>();
for (ConnectorImplementation impl : getImplementations()) {
if (impl != null && definitionId.equals(impl.getDefinitionId())
&& definitionVersion.equals(impl.getDefinitionVersion())) {
implementations.add(impl);
}
}
return implementations;
}
@Override
public IRepositoryFileStore getImplementationFileStore(String implId, String implVersion) {
for (IRepositoryFileStore implStore : getChildren()) {
ConnectorImplementation impl = (ConnectorImplementation) implStore.getContent();
if (impl != null && implId.equals(impl.getImplementationId())
&& implVersion.equals(impl.getImplementationVersion())) {
return implStore;
}
}
return null;
}
@Override
protected void performMigration(Migrator migrator, URI resourceURI,
Release release) throws MigrationException {
migrator.setLevel(ValidationLevel.NONE);
ResourceSet rSet = migrator.migrateAndLoad(
Collections.singletonList(resourceURI), release,
null, Repository.NULL_PROGRESS_MONITOR);
if (!rSet.getResources().isEmpty()) {
FileOutputStream fos = null;
try {
ConnectorImplementationResourceImpl r = (ConnectorImplementationResourceImpl) rSet.getResources().get(0);
Resource resource = new XMLResourceImpl(resourceURI);
org.bonitasoft.studio.connector.model.implementation.DocumentRoot root = ConnectorImplementationFactory.eINSTANCE.createDocumentRoot();
final ConnectorImplementation definition = EcoreUtil.copy(((org.bonitasoft.studio.connector.model.implementation.DocumentRoot) r.getContents()
.get(0)).getConnectorImplementation());
root.setConnectorImplementation(definition);
resource.getContents().add(root);
Map<String, String> options = new HashMap<String, String>();
options.put(XMLResource.OPTION_ENCODING, "UTF-8");
options.put(XMLResource.OPTION_XML_VERSION, "1.0");
File target = new File(resourceURI.toFileString());
fos = new FileOutputStream(target);
new ConnectorImplementationXMLProcessor().save(fos, resource, options);
} catch (Exception e) {
BonitaStudioLog.error(e);
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
BonitaStudioLog.error(e);
}
}
}
}
}
@Override
protected T doImportInputStream(String fileName, InputStream inputStream) {
T fStore = super.doImportInputStream(fileName, inputStream);
cleanJarDependency(fStore, RepositoryManager.getInstance().getRepositoryStore(DependencyRepositoryStore.class), getSourceRepositoryStore());
return fStore;
}
protected abstract IRepositoryStore<? extends IRepositoryFileStore> getSourceRepositoryStore();
protected void cleanJarDependency(IRepositoryFileStore fStore, IRepositoryStore<? extends IRepositoryFileStore> dependencyRepositoryStore,
IRepositoryStore<? extends IRepositoryFileStore> sourceRepositoryStore) {
ConnectorImplementation content = (ConnectorImplementation) fStore.getContent();
if (hasSources(content, sourceRepositoryStore)) {
JarDependencies jarDependencies = content.getJarDependencies();
if (jarDependencies != null) {