Java tutorial
/* * Copyright 2018 Red Hat, Inc. and/or its affiliates. * * 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 org.kie.workbench.common.migration; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.nio.charset.Charset; import java.nio.file.Paths; import java.security.Permission; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import org.apache.commons.io.FileUtils; import org.apache.maven.model.Model; import org.apache.maven.model.io.xpp3.MavenXpp3Reader; import org.apache.tools.ant.ExitException; import org.codehaus.plexus.util.xml.pull.XmlPullParserException; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.ResetCommand; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.revwalk.RevCommit; import org.junit.BeforeClass; import org.junit.Test; import org.kie.workbench.common.forms.data.modeller.model.DataObjectFormModel; import org.kie.workbench.common.forms.fields.test.TestMetaDataEntryManager; import org.kie.workbench.common.forms.jbpm.model.authoring.process.BusinessProcessFormModel; import org.kie.workbench.common.forms.jbpm.model.authoring.task.TaskFormModel; import org.kie.workbench.common.forms.model.FieldDefinition; import org.kie.workbench.common.forms.model.FormDefinition; import org.kie.workbench.common.forms.services.backend.serialization.FormDefinitionSerializer; import org.kie.workbench.common.forms.services.backend.serialization.impl.FieldSerializer; import org.kie.workbench.common.forms.services.backend.serialization.impl.FormDefinitionSerializerImpl; import org.kie.workbench.common.forms.services.backend.serialization.impl.FormModelSerializer; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; import static org.assertj.core.api.Assertions.assertThat; public class MigrationToolTest { private static final File NIOGIT_DIR = Paths.get("target/niogit").toFile(); private static final String GIT_SUFFIX = ".git", PROJECT_A1 = "projectA1", PROJECT_B1 = "projectB1", PROJECT_B2 = "projectB2", PROJECT_B3 = "projectB3", PROJECT_WITH_HISTORY_1 = "projectWithHistory1", PROJECT_WITH_HISTORY_2 = "projectWithHistory2", PROJECT_WITH_FORMS = "projectWithForms", SPACE_A = "spaceA", SPACE_B = "spaceB", SPACE_C = "spaceC", SPACE_SYSTEM = "system", SPACE_EXAMPLE = "example"; private static final FormDefinitionSerializer FORM_SERIALIZER = new FormDefinitionSerializerImpl( new FieldSerializer(), new FormModelSerializer(), new TestMetaDataEntryManager()); private static SecurityManager originalSecurityManager; private static class NoExitSecurityManager extends SecurityManager { @Override public void checkPermission(Permission perm) { } @Override public void checkPermission(Permission perm, Object context) { } @Override public void checkExit(int status) { super.checkExit(status); throw new ExitException(status); } } @BeforeClass public static void runToolAndCloneProjectRepos() throws GitAPIException { originalSecurityManager = System.getSecurityManager(); System.setSecurityManager(new NoExitSecurityManager()); try { runMigrationTool(); } catch (ExitException e) { assertThat(e.getStatus()).isEqualTo(0); } finally { System.setSecurityManager(originalSecurityManager); } cloneAllProjectRepos(); } @Test public void testNewProjectStructure() { final String[] actualSpaceDirs = NIOGIT_DIR.list(); assertThat(actualSpaceDirs).containsExactlyInAnyOrder(SPACE_A, SPACE_B, SPACE_C, SPACE_EXAMPLE, SPACE_SYSTEM); assertThat(getProjectRepos(SPACE_SYSTEM)).containsExactlyInAnyOrder("metadata.git", "plugins.git", "datasets.git", "preferences.git", "system.git"); assertThat(getProjectRepos(SPACE_A)).containsExactly(PROJECT_A1 + GIT_SUFFIX); assertThat(getProjectRepos(SPACE_B)).containsExactlyInAnyOrder(PROJECT_B1 + GIT_SUFFIX, PROJECT_B2 + GIT_SUFFIX, PROJECT_B3 + GIT_SUFFIX, PROJECT_WITH_HISTORY_1 + GIT_SUFFIX, PROJECT_WITH_HISTORY_2 + GIT_SUFFIX, PROJECT_WITH_FORMS + GIT_SUFFIX); assertThat(getProjectRepos(SPACE_C)).isEmpty(); checkProjectFiles(SPACE_A, PROJECT_A1); checkProjectFiles(SPACE_B, PROJECT_B1); checkProjectFiles(SPACE_B, PROJECT_B2); checkProjectFiles(SPACE_B, PROJECT_B3); } @Test public void testNewPomStructure() throws IOException, XmlPullParserException { final File projectDir = getProjectDir(SPACE_B, PROJECT_B2), pom = new File(projectDir, "pom.xml"); final MavenXpp3Reader reader = new MavenXpp3Reader(); final Model model = reader.read(new FileInputStream(pom)); assertThat(model.getVersion()).isEqualTo("1.2.3"); assertThat(model.getDependencies()).hasSize(6); assertThat(model.getBuild().getPlugins()).hasSize(1); assertThat(model.getPackaging()).isEqualTo("kjar"); } @Test public void testProjectGitHistory() throws IOException, GitAPIException { final int latestCommit = 0, previousCommit = 1; final String javaComment = "// ", firstCommitMsg = "first", thirdCommitMsg = "third", fourthCommitMsg = "fourth", fifthCommitMsg = "fifth", drl1Location = "src/main/resources/bxms/projectwithhistory1/drlWithGitHistory1.drl", drl2Location = "src/main/resources/bxms/projectwithhistory2/drlWithGitHistory2.drl"; final File projectWithHistory1 = getProjectDir(SPACE_B, PROJECT_WITH_HISTORY_1), projectWithHistory2 = getProjectDir(SPACE_B, PROJECT_WITH_HISTORY_2), drl1 = new File(projectWithHistory1, drl1Location), drl2 = new File(projectWithHistory2, drl2Location); final Git repoFirst = Git.open(projectWithHistory1), repoSecond = Git.open(projectWithHistory2); final List<String> commitMessagesDrl1 = getDrlCommitMessages(repoFirst, drl1Location), commitMessagesDrl2 = getDrlCommitMessages(repoSecond, drl2Location); assertThat(commitMessagesDrl1).hasSize(4); assertThat(commitMessagesDrl2).hasSize(3); assertThat(commitMessagesDrl1.get(latestCommit)).startsWith(fifthCommitMsg); assertThat(commitMessagesDrl1.get(previousCommit)).startsWith(fourthCommitMsg); assertThat(commitMessagesDrl2.get(latestCommit)).startsWith(thirdCommitMsg); assertThat(commitMessagesDrl2.get(previousCommit)).startsWith(firstCommitMsg); assertThat(getDrlLineWithContent(drl1)).isEqualTo(javaComment + fifthCommitMsg); assertThat(getDrlLineWithContent(drl2)).isEqualTo(javaComment + thirdCommitMsg); resetRepoToPreviousDrlCommit(repoFirst); resetRepoToPreviousDrlCommit(repoSecond); assertThat(getDrlLineWithContent(drl1)).isEqualTo(javaComment + fourthCommitMsg); assertThat(getDrlLineWithContent(drl2)).isEqualTo(javaComment + firstCommitMsg); } @Test public void testTaskForm() throws IOException { final FormDefinition taskFormDef = getFormFromResources("taskWithDifferentIO-taskform"); checkFields(taskFormDef, new HashMap<String, List<String>>() { { put("boolean", Arrays.asList("_boolean (boolean)", "CheckBox", "_boolean")); put("cv", Arrays.asList("_cv (cv)", "Document", "_cv")); put("float", Arrays.asList("_float (float)", "DecimalBox", "_float")); put("integer", Arrays.asList("_integer (integer)", "IntegerBox", "_integer")); put("string", Arrays.asList("_string (string)", "TextBox", "_string")); put("person", Arrays.asList("person", "SubForm", "_person")); } }); assertThat(((TaskFormModel) taskFormDef.getModel()).getTaskName()).isEqualTo("taskWithDifferentIO"); } @Test public void testPersonForm() throws IOException { final FormDefinition personFormDef = getFormFromResources("PersonForm"); final LayoutTemplate layout = personFormDef.getLayoutTemplate(); checkFields(personFormDef, new HashMap<String, List<String>>() { { put("person_address", Arrays.asList("address (person)", "SubForm", "address")); put("person_addressList", Arrays.asList("addressList (person)", "MultipleSubForm", "addressList")); put("person_age", Arrays.asList("age (person)", "IntegerBox", "age")); put("person_birthdate", Arrays.asList("birthdate (person)", "DatePicker", "birthdate")); put("person_married", Arrays.asList("married (person)", "CheckBox", "married")); put("person_name", Arrays.asList("name (person)", "TextBox", "name")); put("person_salary", Arrays.asList("salary (person)", "DecimalBox", "salary")); put("person_sex", Arrays.asList("sex (person)", "TextBox", "sex")); } }); assertThat(layout.getRows()).hasSize(4); assertThat(layout.getRows().get(0).getLayoutColumns()).hasSize(2); assertThat(personFormDef.getFieldByName("person_salary").getHelpMessage()) .isEqualTo("Please enter your salary in dollars."); assertThat(personFormDef.getFieldByName("person_birthdate").getRequired()).isTrue(); assertThat(personFormDef.getFieldByName("person_married").getReadOnly()).isTrue(); assertThat(((DataObjectFormModel) personFormDef.getModel()).getType()) .isEqualTo("bxms.projectWithForms.Person"); } @Test public void testProcessForm() throws IOException { final FormDefinition processFormDef = getFormFromResources( "formmodeler-migration.UpdateUserProfile-taskform"); checkFields(processFormDef, new HashMap<String, List<String>>() { { put("boolean", Arrays.asList("boolean (boolean)", "CheckBox", "boolean")); put("cv", Arrays.asList("cv (cv)", "Document", "cv")); put("float", Arrays.asList("float (float)", "DecimalBox", "float")); put("integer", Arrays.asList("integer (integer)", "IntegerBox", "integer")); put("string", Arrays.asList("string (string)", "TextBox", "string")); put("person", Arrays.asList("person", "SubForm", "person")); } }); assertThat(((BusinessProcessFormModel) processFormDef.getModel()).getProcessName()) .isEqualTo("UpdateUserProfile"); } @Test public void testHelperSubForms() throws IOException { final File helperFormsDir = getFile(SPACE_B, PROJECT_WITH_FORMS, "src/main/resources/bxms/projectWithForms/"); final List<String> helperFormActualFields = getFormFromResources("taskWithSameIO-taskform-person") .getFields().stream().map(FieldDefinition::getName).collect(Collectors.toList()); assertThat(helperFormsDir.list()).contains("formmodeler-migration.UpdateUserProfile-taskform-person.frm", "taskWithDifferentIO-taskform-person.frm", "taskWithSameIO-taskform-person.frm"); assertThat(helperFormActualFields).containsExactlyInAnyOrder("person_address", "person_addressList", "person_birthdate", "person_married", "person_salary", "person_sex"); } private void checkProjectFiles(final String spaceName, final String projectName) { final String assetId = projectName.substring(projectName.length() - 2), projectNamePkg = projectName.toLowerCase(), assetIdResource = assetId.toLowerCase(), drlPath = String.format("/src/main/resources/bxms/%s/drl%s.drl", projectNamePkg, assetIdResource), processPath = String.format("/src/main/resources/bxms/%s/process%s.bpmn2", projectNamePkg, assetIdResource), dataObjectPath = String.format("/src/main/java/bxms/%s/Object%s.java", projectNamePkg, assetId); final File drl = getFile(spaceName, projectName, drlPath), process = getFile(spaceName, projectName, processPath), dataObject = getFile(spaceName, projectName, dataObjectPath); assertThat(drl).exists(); assertThat(process).exists(); assertThat(dataObject).exists(); } private void resetRepoToPreviousDrlCommit(final Git projectRepo) throws GitAPIException { final String previousDrlCommitRef = "HEAD~2"; projectRepo.reset().setMode(ResetCommand.ResetType.HARD).setRef(previousDrlCommitRef).call(); } private void checkFields(final FormDefinition form, final Map<String, List<String>> expectedFields) { final Map<String, List<String>> actualFields = form.getFields().stream() .collect(Collectors.toMap(FieldDefinition::getName, f -> Arrays.asList(f.getLabel(), f.getFieldType().getTypeName(), f.getBinding()))); assertThat(actualFields).isEqualTo(expectedFields); } private List<String> getDrlCommitMessages(final Git repo, final String drlLocation) throws GitAPIException { final Iterable<RevCommit> projectCommits = repo.log().addPath(drlLocation).call(); final List<String> commitMessages = new ArrayList<>(); for (RevCommit c : projectCommits) { commitMessages.add(c.getFullMessage()); } return commitMessages; } private String getDrlLineWithContent(final File drlWithGitHistory) throws IOException { final int lineWithContent = 2; return FileUtils.readLines(drlWithGitHistory, Charset.defaultCharset()).get(lineWithContent); } private FormDefinition getFormFromResources(final String formName) throws IOException { final String formLocation = String.format("src/main/resources/bxms/%s/%s.frm", PROJECT_WITH_FORMS, formName); final File form = getFile(SPACE_B, PROJECT_WITH_FORMS, formLocation); final String formContent = FileUtils.readFileToString(form, Charset.defaultCharset()); return FORM_SERIALIZER.deserialize(formContent); } private static void runMigrationTool() { String[] args = { "-b", "-t", NIOGIT_DIR.getAbsolutePath() }; Main.main(args); } private static void cloneAllProjectRepos() throws GitAPIException { cloneProjectRepo(SPACE_A, PROJECT_A1); cloneProjectRepo(SPACE_B, PROJECT_B1); cloneProjectRepo(SPACE_B, PROJECT_B2); cloneProjectRepo(SPACE_B, PROJECT_B3); cloneProjectRepo(SPACE_B, PROJECT_WITH_FORMS); cloneProjectRepo(SPACE_B, PROJECT_WITH_HISTORY_1); cloneProjectRepo(SPACE_B, PROJECT_WITH_HISTORY_2); } private static void cloneProjectRepo(final String spaceName, final String projectName) throws GitAPIException { final File projectDir = getProjectDir(spaceName, projectName); final String projectRepoDir = getProjectRepoDir(spaceName, projectName).getAbsolutePath(); Git.cloneRepository().setURI(projectRepoDir).setDirectory(projectDir).call(); } private static List<String> getProjectRepos(final String spaceName) { String[] spaceFiles = new File(NIOGIT_DIR, spaceName).list(); return Arrays.stream(spaceFiles).filter(f -> f.endsWith(GIT_SUFFIX)).collect(Collectors.toList()); } private static File getProjectRepoDir(final String spaceName, final String projectName) { final File spaceDir = getSpaceDir(spaceName); return new File(spaceDir, projectName + GIT_SUFFIX); } private static File getProjectDir(final String spaceName, final String projectName) { final File spaceDir = getSpaceDir(spaceName); return new File(spaceDir, projectName); } private static File getSpaceDir(final String spaceName) { return new File(NIOGIT_DIR, spaceName); } private static File getFile(final String spaceName, final String projectName, final String fileLocation) { final File projectDir = getProjectDir(spaceName, projectName); return new File(projectDir, fileLocation); } }