[TRUNK][UPDATE]

- removes WorkflowTemplate
- modifies workflow because of removed templates
- modifies conversions

git-svn-id: https://svn.libreccm.org/ccm/trunk@5088 8810af33-2d31-482b-a856-94f89814c4df
master
tosmers 2017-10-27 15:47:58 +00:00
parent 75080d890f
commit a19c9787fb
19 changed files with 624 additions and 310 deletions

View File

@ -27,7 +27,6 @@ import com.arsdigita.portation.conversion.core.security.UserConversion;
import com.arsdigita.portation.conversion.core.workflow.AssignableTaskConversion; import com.arsdigita.portation.conversion.core.workflow.AssignableTaskConversion;
import com.arsdigita.portation.conversion.core.workflow.TaskCommentConversion; import com.arsdigita.portation.conversion.core.workflow.TaskCommentConversion;
import com.arsdigita.portation.conversion.core.workflow.WorkflowConversion; import com.arsdigita.portation.conversion.core.workflow.WorkflowConversion;
import com.arsdigita.portation.conversion.core.workflow.WorkflowTemplateConversion;
import com.arsdigita.portation.modules.core.security.Permission; import com.arsdigita.portation.modules.core.security.Permission;
@ -71,7 +70,6 @@ public class CoreConverter extends AbstractConverter {
} }
} }
WorkflowTemplateConversion.convertAll();
WorkflowConversion.convertAll(); WorkflowConversion.convertAll();
TaskCommentConversion.convertAll(); TaskCommentConversion.convertAll();
AssignableTaskConversion.convertAll(); AssignableTaskConversion.convertAll();

View File

@ -21,13 +21,22 @@ package com.arsdigita.portation.conversion;
import com.arsdigita.portation.modules.core.categorization.Categorization; import com.arsdigita.portation.modules.core.categorization.Categorization;
import com.arsdigita.portation.modules.core.categorization.Category; import com.arsdigita.portation.modules.core.categorization.Category;
import com.arsdigita.portation.modules.core.core.CcmObject; import com.arsdigita.portation.modules.core.core.CcmObject;
import com.arsdigita.portation.modules.core.security.*; import com.arsdigita.portation.modules.core.security.Group;
import com.arsdigita.portation.modules.core.workflow.*; import com.arsdigita.portation.modules.core.security.GroupMembership;
import com.arsdigita.portation.modules.core.security.Party;
import com.arsdigita.portation.modules.core.security.Permission;
import com.arsdigita.portation.modules.core.security.Role;
import com.arsdigita.portation.modules.core.security.RoleMembership;
import com.arsdigita.portation.modules.core.security.User;
import com.arsdigita.portation.modules.core.workflow.AssignableTask;
import com.arsdigita.portation.modules.core.workflow.Task;
import com.arsdigita.portation.modules.core.workflow.TaskAssignment;
import com.arsdigita.portation.modules.core.workflow.TaskComment;
import com.arsdigita.portation.modules.core.workflow.Workflow;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.TreeMap;
/** /**
* Storage class for all ng-objects after conversion. This also helps for an * Storage class for all ng-objects after conversion. This also helps for an
@ -46,11 +55,10 @@ public class NgCoreCollection {
public static Map<Long, RoleMembership> roleMemberships = new HashMap<>(); public static Map<Long, RoleMembership> roleMemberships = new HashMap<>();
public static Map<Long, CcmObject> ccmObjects = new HashMap<>(); public static Map<Long, CcmObject> ccmObjects = new HashMap<>();
public static Map<Long, Category> categories = new TreeMap<>(); public static Map<Long, Category> categories = new HashMap<>();
public static Map<Long, Categorization> categorizations = new HashMap<>(); public static Map<Long, Categorization> categorizations = new HashMap<>();
public static Map<Long, Workflow> workflows = new HashMap<>(); public static Map<Long, Workflow> workflows = new HashMap<>();
public static Map<Long, WorkflowTemplate> workflowTemplates = new HashMap<>();
public static Map<Long, TaskComment> taskComments = new HashMap<>(); public static Map<Long, TaskComment> taskComments = new HashMap<>();
public static Map<Long, Task> tasks = new HashMap<>(); public static Map<Long, Task> tasks = new HashMap<>();
public static Map<Long, AssignableTask> assignableTasks = new HashMap<>(); public static Map<Long, AssignableTask> assignableTasks = new HashMap<>();
@ -58,70 +66,46 @@ public class NgCoreCollection {
public static Map<Long, Permission> permissions = new HashMap<>(); public static Map<Long, Permission> permissions = new HashMap<>();
// in case maps need to be sorted for export
// if lists need to be sorted in specific way to work with import
public static ArrayList<Category> sortedCategories; public static ArrayList<Category> sortedCategories;
public static ArrayList<Workflow> sortedWorkflows;
public static ArrayList<AssignableTask> sortedAssignableTasks;
/** /**
* Private constructor to prevent the instantiation of this class. * Private constructor to prevent the instantiation of this class.
*/ */
private NgCoreCollection() {} private NgCoreCollection() {}
/** /*
* Sorts values of category-map to ensure that the parent-categories will * Sorts values of task-map to ensure that the dependsOn-tasks will
* be listed before their childs in the export file. * be listed before their dependant task in the export file.
* *
* Runs once over the unsorted list and iterates over each their parents * Runs once over the unsorted list and iterates over each their parents
* to add them to the sorted list. After being added to the sorted list the * to add them to the sorted list. After being added to the sorted list the
* category will be removed from the unsorted list and therefore ignored * task will be removed from the unsorted list and therefore ignored
* in this foreach run. * in this foreach run.
*/ *
public static void sortCategories() { public static void sortAssignableTasks() {
ArrayList<Category> unsortedCategories = ArrayList<AssignableTask> unsortedAssignableTasks =
new ArrayList<>(categories.values()); new ArrayList<>(assignableTasks.values());
sortedCategories = new ArrayList<>(unsortedCategories.size()); sortedAssignableTasks = new ArrayList<>(unsortedAssignableTasks.size());
int runs = 0; int runs = 0;
for (Category anUnsorted : unsortedCategories) { for (AssignableTask anUnsorted : unsortedAssignableTasks) {
add(anUnsorted); addDependencyTasks(anUnsorted);
runs++; runs++;
} }
System.err.printf("\t\tSorted categories in %d runs.\n", runs); System.err.printf("\t\tSorted categories in %d runs.\n", runs);
} }
/** private static void addDependencyTasks(AssignableTask anUnsorted) {
* Helper method to recursively add all parent categories before their List<Task> dependencies = anUnsorted.getDependsOn();
* childs.
* for (Task task : dependencies) {
* @param category the current category in the unsorted list AssignableTask assignableTask = (AssignableTask) task;
}
}
*/ */
private static void add(Category category) {
Category parent = category.getParentCategory();
if (parent != null && !sortedCategories.contains(parent)) {
add(parent);
}
if (!sortedCategories.contains(category)) {
sortedCategories.add(category);
}
}
/**
* Removes the workflow templates from the list of all workflows for
* easier importation in ng as workflow is the parent class of all
* templates. Now you don't have to consider the already imported
* templates while importing all other workflows and being in danger of
* duplications.
*/
public static void removeTemplatesFromWorkflows() {
int removed = 0;
for (long templateId : workflowTemplates.keySet()) {
workflows.remove(templateId);
removed++;
}
System.err.printf("\t\tRemoved %d templates from over all workflows." +
"\n", removed);
}
} }

View File

@ -25,6 +25,7 @@ import com.arsdigita.portation.modules.core.categorization.Categorization;
import com.arsdigita.portation.modules.core.categorization.Category; import com.arsdigita.portation.modules.core.categorization.Category;
import com.arsdigita.portation.modules.core.core.CcmObject; import com.arsdigita.portation.modules.core.core.CcmObject;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
@ -54,7 +55,7 @@ public class CategoryConversion {
createCategoryAndCategorizations(trunkCategories); createCategoryAndCategorizations(trunkCategories);
setRingAssociations(trunkCategories); setRingAssociations(trunkCategories);
System.err.printf("\tSorting categories...\n"); System.err.printf("\tSorting categories...\n");
NgCoreCollection.sortCategories(); sortCategoryMap();
System.err.println("\tdone.\n"); System.err.println("\tdone.\n");
} }
@ -144,8 +145,9 @@ public class CategoryConversion {
for (com.arsdigita.categorization.Category for (com.arsdigita.categorization.Category
trunkCategory : trunkCategories) { trunkCategory : trunkCategories) {
Category category = NgCoreCollection.categories.get(trunkCategory Category category = NgCoreCollection
.getID().longValue()); .categories
.get(trunkCategory.getID().longValue());
// set parent and opposed association // set parent and opposed association
Category parentCategory = null; Category parentCategory = null;
@ -154,14 +156,59 @@ public class CategoryConversion {
trunkCategory.getDefaultParentCategory(); trunkCategory.getDefaultParentCategory();
if (defaultParent != null) { if (defaultParent != null) {
parentCategory = NgCoreCollection.categories.get( parentCategory = NgCoreCollection
.categories
.get(
defaultParent.getID().longValue()); defaultParent.getID().longValue());
} }
} catch (Exception e) {} } catch (Exception ignored) {}
if (category != null && parentCategory != null) { if (category != null && parentCategory != null) {
category.setParentCategory(parentCategory); category.setParentCategory(parentCategory);
parentCategory.addSubCategory(category); parentCategory.addSubCategory(category);
} }
} }
} }
/**
* Sorts values of category-map to ensure that the parent-categories will
* be listed before their childs in the export file.
*
* Runs once over the unsorted map and iterates over each their parents
* to add them to the sorted list.
*/
private static void sortCategoryMap() {
ArrayList<Category> sortedList = new ArrayList<>();
int runs = 0;
for (Category category : NgCoreCollection.categories.values()) {
addParent(sortedList, category);
if (!sortedList.contains(category))
sortedList.add(category);
runs++;
}
NgCoreCollection.sortedCategories = sortedList;
System.err.printf("\t\tSorted categories in %d runs.\n", runs);
}
/**
* Recursively adds the parents of the given category to the sorted list
* to guaranty that the parents will be imported before their childs.
*
* @param sortedList Map of already sorted categories
* @param category Current category
*/
private static void addParent(ArrayList<Category> sortedList, Category
category) {
Category parent = category.getParentCategory();
if (parent != null) {
addParent(sortedList, parent);
if (!sortedList.contains(parent))
sortedList.add(parent);
}
}
} }

View File

@ -164,8 +164,6 @@ public class PermissionConversion {
.get("id")).longValue() .get("id")).longValue()
|| -200 == ((BigDecimal) trunkPermission.getPartyOID() || -200 == ((BigDecimal) trunkPermission.getPartyOID()
.get("id")).longValue()) { .get("id")).longValue()) {
/*System.err.println(
"Skiping because it is a internal permission");*/
continue; continue;
} }
@ -248,16 +246,10 @@ public class PermissionConversion {
System.err.printf("PermissionConversation: No Grantee for " + System.err.printf("PermissionConversation: No Grantee for " +
"permission with database id %d%n", ((BigDecimal) "permission with database id %d%n", ((BigDecimal)
trunkPermission.getACSObject().get("id")).longValue()); trunkPermission.getACSObject().get("id")).longValue());
//System.exit(-1);
} else {
/*System.out.printf("Set grantee for permission %d%n%n",
permission.getPermissionId());*/
} }
} }
System.err.printf("\t\t(Created %d duplicates.)\n", System.err.printf("\t\t(Created %d duplicates and created %d new " +
duplicates); "roles.)\n", duplicates, rolesCreated);
System.err.printf("\t\t(Created %d new roles.)\n",
rolesCreated);
} }
/** /**

View File

@ -25,11 +25,13 @@ import com.arsdigita.portation.conversion.NgCoreCollection;
import com.arsdigita.portation.modules.core.security.Role; import com.arsdigita.portation.modules.core.security.Role;
import com.arsdigita.portation.modules.core.security.User; import com.arsdigita.portation.modules.core.security.User;
import com.arsdigita.portation.modules.core.workflow.AssignableTask; import com.arsdigita.portation.modules.core.workflow.AssignableTask;
import com.arsdigita.portation.modules.core.workflow.Task;
import com.arsdigita.portation.modules.core.workflow.TaskAssignment; import com.arsdigita.portation.modules.core.workflow.TaskAssignment;
import com.arsdigita.portation.modules.core.workflow.TaskComment; import com.arsdigita.portation.modules.core.workflow.TaskComment;
import com.arsdigita.portation.modules.core.workflow.Workflow; import com.arsdigita.portation.modules.core.workflow.Workflow;
import com.arsdigita.workflow.simple.Task;
import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@ -57,10 +59,12 @@ public class AssignableTaskConversion {
.arsdigita.workflow.simple.UserTask.getAllObjectUserTasks(); .arsdigita.workflow.simple.UserTask.getAllObjectUserTasks();
System.err.println("done."); System.err.println("done.");
System.err.printf("\tConverting assignable tasks and task " + System.err.printf("\tConverting assignable tasks and task assignments...\n");
"assignments...\n");
createAssignableTasksAndSetAssociations(trunkUserTasks); createAssignableTasksAndSetAssociations(trunkUserTasks);
setTaskRingDependencies(trunkUserTasks); setTaskRingDependencies(trunkUserTasks);
System.err.printf("\tSorting task assignments...\n");
sortAssignableTaskMap();
System.err.println("\tdone.\n"); System.err.println("\tdone.\n");
} }
@ -84,7 +88,7 @@ public class AssignableTaskConversion {
AssignableTask assignableTask = new AssignableTask(trunkUserTask); AssignableTask assignableTask = new AssignableTask(trunkUserTask);
// set workflow and opposed associations // set workflow and opposed associations
com.arsdigita.workflow.simple.Workflow userTaskWorkflow = null; com.arsdigita.workflow.simple.Workflow userTaskWorkflow;
try { try {
userTaskWorkflow = trunkUserTask.getWorkflow(); userTaskWorkflow = trunkUserTask.getWorkflow();
if (userTaskWorkflow != null) { if (userTaskWorkflow != null) {
@ -95,7 +99,7 @@ public class AssignableTaskConversion {
workflow.addTask(assignableTask); workflow.addTask(assignableTask);
} }
} }
} catch (Exception e) {} } catch (Exception ignored) {}
// set taskComments // set taskComments
Iterator commentsIt = trunkUserTask.getComments(); Iterator commentsIt = trunkUserTask.getComments();
@ -197,14 +201,16 @@ public class AssignableTaskConversion {
for (com.arsdigita.workflow.simple.UserTask trunkUserTask : for (com.arsdigita.workflow.simple.UserTask trunkUserTask :
trunkUserTasks) { trunkUserTasks) {
AssignableTask assignableTask = NgCoreCollection.assignableTasks.get(trunkUserTask.getID() AssignableTask assignableTask = NgCoreCollection
.longValue()); .assignableTasks
.get(trunkUserTask.getID().longValue());
Iterator it = trunkUserTask.getDependencies(); Iterator it = trunkUserTask.getDependencies();
while (it.hasNext()) { while (it.hasNext()) {
AssignableTask dependency = NgCoreCollection.assignableTasks.get(((Task) it AssignableTask dependency = NgCoreCollection
.next()) .assignableTasks
.getID().longValue()); .get(((com.arsdigita.workflow.simple
.Task) it.next()).getID().longValue());
if (assignableTask != null && dependency != null) { if (assignableTask != null && dependency != null) {
// set dependencies and opposed // set dependencies and opposed
@ -214,4 +220,56 @@ public class AssignableTaskConversion {
} }
} }
} }
/**
* Sorts values of assignable-task-map to ensure that the dependencies will
* be listed before their dependant tasks in the export file.
*
* Runs once over the unsorted map and iterates over each their dependencies
* to add them to the sorted list.
*/
private static void sortAssignableTaskMap() {
ArrayList<AssignableTask> sortedList = new ArrayList<>();
int runs = 0;
for (AssignableTask assignableTask :
NgCoreCollection.assignableTasks.values()) {
addDependencies(sortedList, assignableTask);
if (!sortedList.contains(assignableTask)) {
sortedList.add(assignableTask);
}
runs++;
}
NgCoreCollection.sortedAssignableTasks = sortedList;
System.err.printf("\t\tSorted assignable tasks in %d runs.\n", runs);
}
/**
* Recursively adds the dependencies of the given assignable task to the
* sorted list to guaranty that the dependencies will be imported before
* their dependant task.
*
* @param sortedList List of already sorted tasks
* @param assignableTask Current assignable task
*/
private static void addDependencies(ArrayList<AssignableTask> sortedList,
AssignableTask assignableTask) {
List<Task> dependencies = assignableTask.getDependsOn();
if (!dependencies.isEmpty()) {
for (Task dependsOnTask : dependencies) {
AssignableTask dependency = (AssignableTask) dependsOnTask;
if (dependency != null) {
addDependencies(sortedList, dependency);
if (!sortedList.contains(dependency))
sortedList.add(dependency);
}
}
}
}
} }

View File

@ -20,11 +20,15 @@ package com.arsdigita.portation.conversion.core.workflow;
import com.arsdigita.kernel.ACSObject; import com.arsdigita.kernel.ACSObject;
import com.arsdigita.portation.conversion.NgCoreCollection; import com.arsdigita.portation.conversion.NgCoreCollection;
import com.arsdigita.portation.modules.core.categorization.Category;
import com.arsdigita.portation.modules.core.core.CcmObject; import com.arsdigita.portation.modules.core.core.CcmObject;
import com.arsdigita.portation.modules.core.workflow.Workflow; import com.arsdigita.portation.modules.core.workflow.Workflow;
import com.arsdigita.portation.modules.core.workflow.WorkflowTemplate; import com.arsdigita.workflow.simple.WorkflowTemplate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* Class for converting all * Class for converting all
@ -50,12 +54,21 @@ public class WorkflowConversion {
System.err.printf("\tConverting workflows...\n"); System.err.printf("\tConverting workflows...\n");
createWorkflowAndSetAssociations(trunkWorkflows); createWorkflowAndSetAssociations(trunkWorkflows);
System.err.printf("\tRemoving workflow templates...\n"); setTemplateAssociations(trunkWorkflows);
NgCoreCollection.removeTemplatesFromWorkflows(); System.err.printf("\tSorting workflows...\n");
sortWorkflowMap();
System.err.println("\tdone.\n"); System.err.println("\tdone.\n");
} }
/**
* Creates the equivalent ng-class of the {@code Workflow} and restores
* the associations to other classes.
*
* @param trunkWorkflows List of all
* {@link com.arsdigita.workflow.simple.Workflow}s
* from this old trunk-system.
*/
private static void createWorkflowAndSetAssociations( private static void createWorkflowAndSetAssociations(
List<com.arsdigita.workflow.simple.Workflow> trunkWorkflows) { List<com.arsdigita.workflow.simple.Workflow> trunkWorkflows) {
int processed = 0; int processed = 0;
@ -63,17 +76,7 @@ public class WorkflowConversion {
for (com.arsdigita.workflow.simple.Workflow for (com.arsdigita.workflow.simple.Workflow
trunkWorkflow : trunkWorkflows) { trunkWorkflow : trunkWorkflows) {
// create workflows // create workflows
Workflow workflow = new Workflow(trunkWorkflow, false); Workflow workflow = new Workflow(trunkWorkflow);
// set template association
com.arsdigita.workflow.simple.WorkflowTemplate
trunkWorkflowTemplate = trunkWorkflow.getWorkflowTemplate();
if (trunkWorkflowTemplate != null) {
WorkflowTemplate workflowTemplate = NgCoreCollection
.workflowTemplates
.get(trunkWorkflowTemplate.getID().longValue());
workflow.setTemplate(workflowTemplate);
}
// set object association // set object association
ACSObject trunkObject = trunkWorkflow.getObject(); ACSObject trunkObject = trunkWorkflow.getObject();
@ -89,4 +92,83 @@ public class WorkflowConversion {
System.err.printf("\t\tCreated %d workflows.\n", processed); System.err.printf("\t\tCreated %d workflows.\n", processed);
} }
/**
* Set the template associations, because an equivalent class for
* templates does not exists in the ng-system.
*
* @param trunkWorkflows List of all
* {@link com.arsdigita.workflow.simple.Workflow}s
* from this old trunk-system.
*/
private static void setTemplateAssociations(
List<com.arsdigita.workflow.simple.Workflow> trunkWorkflows) {
int processed = 0;
for (com.arsdigita.workflow.simple.Workflow trunkWorkflow :
trunkWorkflows) {
Workflow workflow = NgCoreCollection
.workflows
.get(trunkWorkflow.getID().longValue());
// set template associations
WorkflowTemplate trunkWorkflowTemplate = trunkWorkflow
.getWorkflowTemplate();
if (trunkWorkflowTemplate != null) {
Workflow template = NgCoreCollection
.workflows
.get(trunkWorkflowTemplate.getID().longValue());
workflow.setTemplate(template);
template.setAbstractWorkflow(true);
} else
processed++;
}
System.err.printf("\t\tFound %d templates.\n", processed);
}
/**
* Sorts values of workflow-map to ensure that the template-workflows will
* be listed before the workflows constructed with this templates in the
* export file.
*
* Runs once over the unsorted list and iterates over each their templates
* to add them to the sorted list.
*/
private static void sortWorkflowMap() {
ArrayList<Workflow> sortedList = new ArrayList<>();
int runs = 0;
for (Workflow workflow : NgCoreCollection.workflows.values()) {
addTemplate(sortedList, workflow);
if (!sortedList.contains(workflow)) {
sortedList.add(workflow);
}
runs++;
}
NgCoreCollection.sortedWorkflows = sortedList;
System.err.printf("\t\tSorted workflows in %d runs.\n", runs);
}
/**
* Recursively adds the template of the given workflow to the sorted list
* to guaranty that the templates will be imported before their workflows.
*
* @param sortedList List of already sorted workflows
* @param workflow Current workflow
*/
private static void addTemplate(ArrayList<Workflow> sortedList, Workflow
workflow) {
Workflow template = workflow.getTemplate();
if (template != null) {
addTemplate(sortedList, template);
if (!sortedList.contains(template))
sortedList.add(template);
}
}
} }

View File

@ -1,59 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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 library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.portation.conversion.core.workflow;
import com.arsdigita.portation.modules.core.workflow.WorkflowTemplate;
import java.util.List;
/**
* Class for converting all
* trunk-{@link com.arsdigita.workflow.simple.WorkflowTemplate}s into
* ng-{@link WorkflowTemplate}s as preparation for a successful export of all
* trunk classes into the new ng-system.
*
* @author <a href="mailto:tosmers@uni-bremen.de>Tobias Osmers</a>
* @version created on 11/21/16
*/
public class WorkflowTemplateConversion {
/**
* Retrieves all
* trunk-{@link com.arsdigita.workflow.simple.WorkflowTemplate}s from
* the persistent storage and collects them in a list. Then calls for
* creating the equivalent ng-{@link WorkflowTemplate}s.
*/
public static void convertAll() {
System.err.printf("\tFetching workflow templates from database...");
List<com.arsdigita.workflow.simple.WorkflowTemplate>
trunkWorkflowTemplates = com.arsdigita.workflow.simple
.WorkflowTemplate.getAllObjectWorkflowTemplates();
System.err.println("done.");
System.err.printf("\tConverting workflow templates...\n");
int processed = 0;
for (com.arsdigita.workflow.simple.WorkflowTemplate
trunkWorkflowTemplate : trunkWorkflowTemplates) {
new WorkflowTemplate(trunkWorkflowTemplate);
processed++;
}
System.out.printf("\t\tCreated %d workflow templates.\n", processed);
System.err.println("\tdone.\n");
}
}

View File

@ -48,7 +48,6 @@ public class CoreExporter extends AbstractExporter {
exportPermissions(); exportPermissions();
exportWorkflowTemplates();
exportWorkflows(); exportWorkflows();
exportTaskComments(); exportTaskComments();
exportAssignableTasks(); exportAssignableTasks();
@ -113,7 +112,8 @@ public class CoreExporter extends AbstractExporter {
CategoryMarshaller categoryMarshaller = new CategoryMarshaller(); CategoryMarshaller categoryMarshaller = new CategoryMarshaller();
categoryMarshaller.prepare( categoryMarshaller.prepare(
Format.XML, pathName, "categories", indentation); Format.XML, pathName, "categories", indentation);
categoryMarshaller.exportList(NgCoreCollection.sortedCategories); categoryMarshaller.exportList(
NgCoreCollection.sortedCategories);
System.out.printf("\t\tdone.\n"); System.out.printf("\t\tdone.\n");
} }
@ -139,24 +139,13 @@ public class CoreExporter extends AbstractExporter {
System.out.printf("\tdone.\n"); System.out.printf("\tdone.\n");
} }
private static void exportWorkflowTemplates() {
System.out.printf("\tExporting workflow templates...");
WorkflowTemplateMarshaller workflowTemplateMarshaller = new
WorkflowTemplateMarshaller();
workflowTemplateMarshaller.prepare(
Format.XML, pathName, "workflowTemplates", indentation);
workflowTemplateMarshaller.exportList(
new ArrayList<>(NgCoreCollection.workflowTemplates.values()));
System.out.printf("\tdone.\n");
}
private static void exportWorkflows() { private static void exportWorkflows() {
System.out.printf("\tExporting workflows..."); System.out.printf("\tExporting workflows...");
WorkflowMarshaller workflowMarshaller = new WorkflowMarshaller(); WorkflowMarshaller workflowMarshaller = new WorkflowMarshaller();
workflowMarshaller.prepare( workflowMarshaller.prepare(
Format.XML, pathName, "workflows", indentation); Format.XML, pathName, "workflows", indentation);
workflowMarshaller.exportList( workflowMarshaller.exportList(
new ArrayList<>(NgCoreCollection.workflows.values())); NgCoreCollection.sortedWorkflows);
System.out.printf("\t\tdone.\n"); System.out.printf("\t\tdone.\n");
} }
@ -178,7 +167,7 @@ public class CoreExporter extends AbstractExporter {
assignableTaskMarshaller.prepare( assignableTaskMarshaller.prepare(
Format.XML, pathName, "assignableTasks", indentation); Format.XML, pathName, "assignableTasks", indentation);
assignableTaskMarshaller.exportList( assignableTaskMarshaller.exportList(
new ArrayList<>(NgCoreCollection.assignableTasks.values())); NgCoreCollection.sortedAssignableTasks);
System.out.printf("\tdone.\n"); System.out.printf("\tdone.\n");
} }

View File

@ -16,14 +16,18 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA * MA 02110-1301 USA
*/ */
package com.arsdigita.portation.modules.core.workflow; package com.arsdigita.portation.modules.core.l10n;
import com.arsdigita.portation.AbstractMarshaller;
/** /**
* @author <a href="mailto:tosmers@uni-bremen.de>Tobias Osmers</a> *
* @version created on 11/21/16 * @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/ */
public class WorkflowTemplateMarshaller extends public final class L10NConstants {
AbstractMarshaller<WorkflowTemplate> {
public static final String L10N_XML_NS = "http://l10n.libreccm.org";
private L10NConstants() {
//Nothing
}
} }

View File

@ -18,10 +18,17 @@
*/ */
package com.arsdigita.portation.modules.core.l10n; package com.arsdigita.portation.modules.core.l10n;
import com.arsdigita.portation.modules.core.l10n.jaxb.LocalizedStringValuesAdapter;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.util.*; import java.util.*;
import static com.arsdigita.portation.modules.core.l10n.L10NConstants.L10N_XML_NS;
/** /**
* A helper class for localisable string properties. This class is declared as * A helper class for localisable string properties. This class is declared as
* embeddable, so that it can be used in every other entity. The localised * embeddable, so that it can be used in every other entity. The localised
@ -31,8 +38,11 @@ import java.util.*;
* @author <a href="mailto:tosmers@uni-bremen.de>Tobias Osmers<\a> * @author <a href="mailto:tosmers@uni-bremen.de>Tobias Osmers<\a>
* @version created on 6/15/16 * @version created on 6/15/16
*/ */
@XmlAccessorType(XmlAccessType.FIELD)
public class LocalizedString { public class LocalizedString {
@XmlElement(name = "values", namespace = L10N_XML_NS)
@XmlJavaTypeAdapter(LocalizedStringValuesAdapter.class)
private Map<Locale, String> values; private Map<Locale, String> values;
/** /**

View File

@ -0,0 +1,111 @@
/*
* Copyright (C) 2017 LibreCCM Foundation.
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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 library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.portation.modules.core.l10n.jaxb;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlValue;
import java.io.Serializable;
import java.util.Objects;
import static com.arsdigita.portation.modules.core.l10n.L10NConstants.L10N_XML_NS;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@XmlAccessorType(XmlAccessType.FIELD)
public class LocalizedStringValue implements Serializable {
private static final long serialVersionUID = 8435485565736441379L;
@XmlAttribute(name = "lang", namespace = L10N_XML_NS)
private String locale;
@XmlValue
private String value;
public String getLocale() {
return locale;
}
public void setLocale(final String locale) {
this.locale = locale;
}
public String getValue() {
return value;
}
public void setValue(final String value) {
this.value = value;
}
@Override
public int hashCode() {
int hash = 3;
hash = 97 * hash + Objects.hashCode(locale);
hash = 97 * hash + Objects.hashCode(value);
return hash;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof LocalizedStringValue)) {
return false;
}
final LocalizedStringValue other = (LocalizedStringValue) obj;
if (!other.canEqual(this)) {
return false;
}
if (!Objects.equals(locale, other.getLocale())) {
return false;
}
return Objects.equals(value, other.getValue());
}
public boolean canEqual(final Object obj) {
return obj instanceof LocalizedStringValue;
}
@Override
public final String toString() {
return toString("");
}
public String toString(final String data) {
return String.format("%s{ "
+ "locale = %s, "
+ "value = \"%s\"%s"
+ " }",
super.toString(),
Objects.toString(locale),
value,
data);
}
}

View File

@ -0,0 +1,97 @@
/*
* Copyright (C) 2017 LibreCCM Foundation.
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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 library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.portation.modules.core.l10n.jaxb;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import static com.arsdigita.portation.modules.core.l10n.L10NConstants.L10N_XML_NS;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@XmlAccessorType(XmlAccessType.FIELD)
public class LocalizedStringValues implements Serializable {
private static final long serialVersionUID = 1L;
@JacksonXmlElementWrapper(useWrapping = false)
@XmlElement(name = "value", namespace = L10N_XML_NS)
private List<LocalizedStringValue> values;
public List<LocalizedStringValue> getValues() {
return new ArrayList<>(values);
}
public void setValues(final List<LocalizedStringValue> values) {
this.values = new ArrayList<>(values);
}
@Override
public int hashCode() {
int hash = 3;
hash = 41 * hash + Objects.hashCode(values);
return hash;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof LocalizedStringValues)) {
return false;
}
final LocalizedStringValues other = (LocalizedStringValues) obj;
if (!other.canEqual(this)) {
return false;
}
return Objects.equals(values, other.getValues());
}
public boolean canEqual(final Object obj) {
return obj instanceof LocalizedStringValues;
}
@Override
public final String toString() {
return toString("");
}
public String toString(final String data) {
return String.format("%s{ "
+ "values = %s%s"
+ " }",
super.toString(),
Objects.toString(values),
data);
}
}

View File

@ -0,0 +1,77 @@
/*
* Copyright (C) 2017 LibreCCM Foundation.
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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 library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.portation.modules.core.l10n.jaxb;
import com.arsdigita.portation.modules.core.l10n.LocalizedString;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;
/**
* JAXB adapter for {@link LocalizedString#values} to produce a more compact XML
* for the values map.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class LocalizedStringValuesAdapter
extends XmlAdapter<LocalizedStringValues, Map<Locale, String>> {
@Override
public Map<Locale, String> unmarshal(final LocalizedStringValues values)
throws Exception {
return values
.getValues()
.stream()
.collect(Collectors.toMap(value -> new Locale(value.getLocale()),
value -> value.getValue()));
}
@Override
public LocalizedStringValues marshal(final Map<Locale, String> values)
throws Exception {
final List<LocalizedStringValue> list = values
.entrySet()
.stream()
.map(this::generateValue)
.collect(Collectors.toList());
final LocalizedStringValues result = new LocalizedStringValues();
result.setValues(list);
return result;
}
private LocalizedStringValue generateValue(
final Map.Entry<Locale, String> entry) {
final LocalizedStringValue value = new LocalizedStringValue();
value.setLocale(entry.getKey().toString());
value.setValue(entry.getValue());
return value;
}
}

View File

@ -44,8 +44,9 @@ public class Workflow implements Portable {
private long workflowId; private long workflowId;
private String uuid; private String uuid;
private boolean abstractWorkflow;
@JsonIdentityReference(alwaysAsId = true) @JsonIdentityReference(alwaysAsId = true)
private WorkflowTemplate template; private Workflow template;
private LocalizedString name; private LocalizedString name;
private LocalizedString description; private LocalizedString description;
private WorkflowState state; private WorkflowState state;
@ -57,11 +58,11 @@ public class Workflow implements Portable {
private List<Task> tasks; private List<Task> tasks;
public Workflow(final com.arsdigita.workflow.simple.Workflow public Workflow(final com.arsdigita.workflow.simple.Workflow trunkWorkFlow) {
trunkWorkFlow, boolean template) {
this.workflowId = trunkWorkFlow.getID().longValue(); this.workflowId = trunkWorkFlow.getID().longValue();
this.uuid = UUID.randomUUID().toString(); this.uuid = UUID.randomUUID().toString();
this.abstractWorkflow = false;
//this.template //this.template
this.name = new LocalizedString(); this.name = new LocalizedString();
@ -79,7 +80,6 @@ public class Workflow implements Portable {
this.tasks = new ArrayList<>(); this.tasks = new ArrayList<>();
if (!template)
NgCoreCollection.workflows.put(this.workflowId, this); NgCoreCollection.workflows.put(this.workflowId, this);
} }
@ -100,11 +100,19 @@ public class Workflow implements Portable {
this.uuid = uuid; this.uuid = uuid;
} }
public WorkflowTemplate getTemplate() { public boolean isAbstractWorkflow() {
return abstractWorkflow;
}
public void setAbstractWorkflow(boolean abstractWorkflow) {
this.abstractWorkflow = abstractWorkflow;
}
public Workflow getTemplate() {
return template; return template;
} }
public void setTemplate(final WorkflowTemplate template) { public void setTemplate(Workflow template) {
this.template = template; this.template = template;
} }

View File

@ -1,40 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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 library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.portation.modules.core.workflow;
import com.arsdigita.portation.conversion.NgCoreCollection;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
/**
* @author <a href="mailto:tosmers@uni-bremen.de>Tobias Osmers</a>
* @version created on 11/18/16
*/
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = WorkflowTemplateIdResolver.class,
property = "uuid")
public class WorkflowTemplate extends Workflow {
public WorkflowTemplate(com.arsdigita.workflow.simple.WorkflowTemplate
trunkWorkFlowTemplate) {
super(trunkWorkFlowTemplate, true);
NgCoreCollection.workflowTemplates.put(this.getWorkflowId(), this);
}
}

View File

@ -1,50 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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 library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.portation.modules.core.workflow;
import com.fasterxml.jackson.annotation.ObjectIdGenerator;
import com.fasterxml.jackson.annotation.ObjectIdResolver;
/**
* @author <a href="mailto:tosmers@uni-bremen.de>Tobias Osmers<\a>
* @version created the 9/6/17
*/
public class WorkflowTemplateIdResolver implements ObjectIdResolver {
@Override
public void bindItem(ObjectIdGenerator.IdKey idKey, Object o) {
// According to the Jackson JavaDoc, this method can be used to keep
// track of objects directly in a resolver implementation. We don't need
// this here therefore this method is empty.
}
@Override
public Object resolveId(ObjectIdGenerator.IdKey idKey) {
return null;
}
@Override
public ObjectIdResolver newForDeserialization(Object o) {
return new WorkflowTemplateIdResolver();
}
@Override
public boolean canUseFor(ObjectIdResolver resolverType) {
return resolverType instanceof WorkflowTemplateIdResolver;
}
}

View File

@ -49,44 +49,4 @@ public class NgCoreCollection {
* Private constructor to prevent the instantiation of this class. * Private constructor to prevent the instantiation of this class.
*/ */
private NgCoreCollection() {} private NgCoreCollection() {}
/**
* Sorts values of resource-map to ensure that the parent-resources will
* be listed before their childs in the export file.
*
* Runs once over the unsorted list and iterates over each their parents
* to add them to the sorted list. After being added to the sorted list the
* resource will be removed from the unsorted list and therefore ignored
* in this foreach run.
*/
public static void sortCcmApplications() {
ArrayList<CcmApplication> unsortedCcmApplications =
new ArrayList<>(ccmApplications.values());
sortedCcmApplications = new ArrayList<>(unsortedCcmApplications.size());
int runs = 0;
for (CcmApplication anUnsorted : unsortedCcmApplications) {
add(anUnsorted);
runs++;
}
System.err.printf("\t\tSorted ccm applications in %d runs.\n", runs);
}
/**
* Helper method to recursively add all parent resources before their
* childs.
*
* @param ccmApplication the current resource in the unsorted list
*/
private static void add(CcmApplication ccmApplication) {
CcmApplication parent = (CcmApplication) ccmApplication.getParent();
if (parent != null && !sortedCcmApplications.contains(parent)) {
add(parent);
}
if (!sortedCcmApplications.contains(ccmApplication)) {
sortedCcmApplications.add(ccmApplication);
}
}
} }

View File

@ -25,6 +25,7 @@ import com.arsdigita.london.terms.portation.modules.core.core.ResourceType;
import com.arsdigita.london.terms.portation.modules.core.web.CcmApplication; import com.arsdigita.london.terms.portation.modules.core.web.CcmApplication;
import com.arsdigita.web.Application; import com.arsdigita.web.Application;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
@ -54,7 +55,7 @@ public class CcmApplicationConversion {
setRingAssociations(trunkApplications); setRingAssociations(trunkApplications);
System.err.printf("\tSorting ccm applications...\n"); System.err.printf("\tSorting ccm applications...\n");
NgCoreCollection.sortCcmApplications(); sortCcmApplications();
System.err.println("\tdone.\n"); System.err.println("\tdone.\n");
} }
@ -121,4 +122,49 @@ public class CcmApplicationConversion {
} }
} }
} }
/**
* Sorts values of resource-map to ensure that the parent-resources will
* be listed before their childs in the export file.
*
* Runs once over the unsorted list and iterates over each their parents
* to add them to the sorted list.
*/
private static void sortCcmApplications() {
ArrayList<CcmApplication> sortedList = new ArrayList<>();
int runs = 0;
for (CcmApplication application : NgCoreCollection.ccmApplications
.values()) {
addResourceParent(sortedList, application);
if (!sortedList.contains(application))
sortedList.add(application);
runs++;
}
NgCoreCollection.sortedCcmApplications = sortedList;
System.err.printf("\t\tSorted ccm applications in %d runs.\n", runs);
}
/**
* Helper method to recursively add all parent resources before their
* childs.
*
* @param sortedList List of already sorted assignable tasks
* @param ccmApplication Current assignable task
*/
private static void addResourceParent(ArrayList<CcmApplication> sortedList,
CcmApplication ccmApplication) {
CcmApplication resourceParent = (CcmApplication) ccmApplication
.getParent();
if (resourceParent != null) {
addResourceParent(sortedList, resourceParent);
if (!sortedList.contains(resourceParent))
sortedList.add(resourceParent);
}
}
} }

View File

@ -65,7 +65,7 @@ public class LdnTermsExporter extends AbstractExporter {
ccmApplicationMarshaller.prepare( ccmApplicationMarshaller.prepare(
Format.XML, pathName, "ccmApplications", indentation); Format.XML, pathName, "ccmApplications", indentation);
ccmApplicationMarshaller.exportList( ccmApplicationMarshaller.exportList(
new ArrayList<>(NgCoreCollection.ccmApplications.values())); NgCoreCollection.sortedCcmApplications);
System.out.printf("\tdone.\n"); System.out.printf("\tdone.\n");
} }