First step to import orders using MPXJ
* Implement the interface OrderImporter using MPXJ * Conversor from MPXJ file types to ImportData * Modify pom.xml to add MPXJ dependency FEA: ItEr77S05BasicProjectImport
This commit is contained in:
parent
59d2a029fc
commit
21a8d1cc68
4 changed files with 430 additions and 0 deletions
|
|
@ -120,6 +120,11 @@
|
|||
<groupId>org.liquibase</groupId>
|
||||
<artifactId>liquibase-maven-plugin</artifactId>
|
||||
</dependency>
|
||||
<!-- MPXJ Library -->
|
||||
<dependency>
|
||||
<groupId>net.sourceforge</groupId>
|
||||
<artifactId>mpxj</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,176 @@
|
|||
/*
|
||||
* This file is part of LibrePlan
|
||||
*
|
||||
* Copyright (C) 2012 Igalia, S.L.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.libreplan.business.orders.imports;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.sf.mpxj.ProjectFile;
|
||||
import net.sf.mpxj.Task;
|
||||
|
||||
/**
|
||||
* Class that is a conversor from the MPXJ format File to {@link ImportData}.
|
||||
*
|
||||
* At these moment it only converts the tasks and its subtasks.
|
||||
*
|
||||
* @author Alba Carro Pérez <alba.carro@gmail.com>
|
||||
* @todo It last relationships. resources, calendars, hours, etc.
|
||||
*/
|
||||
public class MPXJProjectFileConversor {
|
||||
|
||||
/**
|
||||
* Converts a ProjectFile into a {@link ImportData}.
|
||||
*
|
||||
* This method contains a switch that is going to select the method to call
|
||||
* for each format. At this time it only differences between planner and
|
||||
* project.
|
||||
*
|
||||
* @param file
|
||||
* ProjectFile to extract data from.
|
||||
* @return ImportData with the data that we want to import.
|
||||
*/
|
||||
public static ImportData convert(ProjectFile file, String filename) {
|
||||
|
||||
ImportData importData;
|
||||
|
||||
switch (file.getMppFileType()) {
|
||||
|
||||
case 0:
|
||||
importData = getImportDataFromPlanner(file, filename);
|
||||
break;
|
||||
default:
|
||||
importData = getImportDataFromMPP(file, filename);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return importData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a ProjectFile into a {@link ImportData}.
|
||||
*
|
||||
* Assumes that the ProjectFile comes for a .planner file.
|
||||
*
|
||||
* @param file
|
||||
* ProjectFile to extract data from.
|
||||
* @return ImportData with the data that we want to import.
|
||||
*/
|
||||
private static ImportData getImportDataFromPlanner(ProjectFile file,
|
||||
String filename) {
|
||||
|
||||
ImportData importData = new ImportData();
|
||||
|
||||
importData.name = filename
|
||||
.substring(0, filename.length() - 8/* ".planner" */);
|
||||
|
||||
importData.tasks = getImportTasks(file.getChildTasks());
|
||||
|
||||
return importData;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a ProjectFile into a {@link ImportData}
|
||||
*
|
||||
* Assumes that the ProjectFile comes for a .mpp file.
|
||||
*
|
||||
* @param file
|
||||
* ProjectFile to extract data from.
|
||||
* @return ImportData with the data that we want to import.
|
||||
*/
|
||||
private static ImportData getImportDataFromMPP(ProjectFile file,
|
||||
String filename) {
|
||||
|
||||
ImportData importData = new ImportData();
|
||||
|
||||
for (Task task : file.getChildTasks()) {
|
||||
// Projects are represented as a level 0 task with all
|
||||
// real task as its children. Ignore all other top level tasks.
|
||||
// See
|
||||
// http://mpxj.sourceforge.net/faq.html#extra-tasks-and-resources
|
||||
if (task.getChildTasks().size() != 0) {
|
||||
|
||||
String name = task.getName();
|
||||
|
||||
if (name != null) {
|
||||
|
||||
importData.name = name;
|
||||
|
||||
} else {
|
||||
// Take the filename if the project name is not set.
|
||||
importData.name = filename.substring(0,
|
||||
filename.length() - 4/* ".mpp" */);
|
||||
|
||||
}
|
||||
|
||||
importData.tasks = getImportTasks(task.getChildTasks());
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return importData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a List of MPXJ Tasks into a List of {@link ImportTask}.
|
||||
*
|
||||
* @param tasks
|
||||
* List of MPXJ Tasks to extract data from.
|
||||
* @return List<ImportTask> List of ImportTask with the data that we want to
|
||||
* import.
|
||||
*/
|
||||
private static List<ImportTask> getImportTasks(List<Task> tasks) {
|
||||
|
||||
List<ImportTask> importTasks = new ArrayList<ImportTask>();
|
||||
|
||||
for (Task task : tasks) {
|
||||
|
||||
ImportTask importTask = getTaskData(task);
|
||||
|
||||
importTask.children = getImportTasks(task.getChildTasks());
|
||||
|
||||
importTasks.add(importTask);
|
||||
|
||||
}
|
||||
|
||||
return importTasks;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a MPXJ Task into a {@link ImportTask}.
|
||||
*
|
||||
* @param task
|
||||
* MPXJ Task to extract data from.
|
||||
* @return ImportTask ImportTask with the data that we want to import.
|
||||
*/
|
||||
private static ImportTask getTaskData(Task task) {
|
||||
|
||||
ImportTask importTask = new ImportTask();
|
||||
|
||||
importTask.name = task.getName();
|
||||
|
||||
return importTask;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,243 @@
|
|||
/*
|
||||
* This file is part of LibrePlan
|
||||
*
|
||||
* Copyright (C) 2012 Igalia, S.L.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.libreplan.business.orders.imports;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import net.sf.mpxj.reader.ProjectReader;
|
||||
import net.sf.mpxj.reader.ProjectReaderUtility;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.libreplan.business.calendars.entities.BaseCalendar;
|
||||
import org.libreplan.business.common.IAdHocTransactionService;
|
||||
import org.libreplan.business.common.daos.IConfigurationDAO;
|
||||
import org.libreplan.business.common.daos.IEntitySequenceDAO;
|
||||
import org.libreplan.business.common.entities.EntityNameEnum;
|
||||
import org.libreplan.business.orders.daos.IOrderDAO;
|
||||
import org.libreplan.business.orders.entities.Order;
|
||||
import org.libreplan.business.orders.entities.OrderElement;
|
||||
import org.libreplan.business.orders.entities.OrderLine;
|
||||
import org.libreplan.business.orders.entities.OrderLineGroup;
|
||||
import org.libreplan.business.scenarios.IScenarioManager;
|
||||
import org.libreplan.business.scenarios.entities.OrderVersion;
|
||||
import org.libreplan.business.scenarios.entities.Scenario;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
*
|
||||
* Has all the methods needed to successfully import some external project files
|
||||
* into Libreplan using MPXJ.
|
||||
*
|
||||
* @author Alba Carro Pérez <alba.carro@gmail.com>
|
||||
*/
|
||||
@Component
|
||||
@Scope(BeanDefinition.SCOPE_SINGLETON)
|
||||
public class OrderImporterMPXJ implements OrderImporter {
|
||||
|
||||
@Autowired
|
||||
private IEntitySequenceDAO entitySequenceDAO;
|
||||
|
||||
@Autowired
|
||||
protected IAdHocTransactionService transactionService;
|
||||
|
||||
@Autowired
|
||||
private IConfigurationDAO configurationDAO;
|
||||
|
||||
@Autowired
|
||||
private IOrderDAO orderDAO;
|
||||
|
||||
@Autowired
|
||||
private IScenarioManager scenarioManager;
|
||||
|
||||
/**
|
||||
* Makes a {@link ImportData} from a InputStream.
|
||||
*
|
||||
* Uses the filename in order to get the specific ProjectReader for each
|
||||
* kind of file (.mpp, .planner, etc).
|
||||
*
|
||||
* @param file
|
||||
* InputStream to extract data from.
|
||||
* @param filename
|
||||
* String with the name of the original file of the InputStream.
|
||||
* @return ImportData with the data that we want to import.
|
||||
*/
|
||||
@Override
|
||||
public ImportData getImportData(InputStream file, String filename) {
|
||||
try {
|
||||
|
||||
ProjectReader reader = ProjectReaderUtility
|
||||
.getProjectReader(filename);
|
||||
|
||||
return MPXJProjectFileConversor
|
||||
.convert(reader.read(file), filename);
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
throw new RuntimeException(e);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String getCode(EntityNameEnum entity) {
|
||||
|
||||
String code = entitySequenceDAO.getNextEntityCode(entity);
|
||||
|
||||
if (code == null) {
|
||||
throw new ConcurrentModificationException(
|
||||
"Could not retrieve Code. Please, try again later");
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Makes a {@link Order} from a {@link ImportData}.
|
||||
*
|
||||
* @param project
|
||||
* ImportData to extract data from.
|
||||
* @return Order with all the data that we want.
|
||||
*/
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public Order convertImportDataToOrder(ImportData project) {
|
||||
|
||||
String code = getCode(EntityNameEnum.ORDER);
|
||||
|
||||
Scenario current = scenarioManager.getCurrent();
|
||||
|
||||
OrderVersion orderVersion = OrderVersion.createInitialVersion(current);
|
||||
|
||||
Validate.notNull(orderVersion);
|
||||
|
||||
OrderElement orderElement;
|
||||
|
||||
orderElement = Order.createUnvalidated(code);
|
||||
|
||||
((Order) orderElement).setVersionForScenario(current, orderVersion);
|
||||
|
||||
((Order) orderElement).setDependenciesConstraintsHavePriority(true);
|
||||
|
||||
BaseCalendar calendar = configurationDAO.getConfiguration()
|
||||
.getDefaultCalendar();
|
||||
|
||||
((Order) orderElement).setCalendar(calendar);
|
||||
|
||||
orderElement.useSchedulingDataFor(orderVersion);
|
||||
|
||||
List<OrderElement> children = new ArrayList<OrderElement>();
|
||||
|
||||
for (ImportTask task : project.tasks) {
|
||||
children.add(convertImportTaskToOrderElement(orderVersion, task));
|
||||
}
|
||||
|
||||
for (OrderElement child : children) {
|
||||
((OrderLineGroup) orderElement).add(child);
|
||||
}
|
||||
|
||||
orderElement.setName(project.name + ": " + project.hashCode());
|
||||
orderElement.setCode(code);
|
||||
|
||||
orderElement.setInitDate(new Date());
|
||||
|
||||
return (Order) orderElement;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Private method.
|
||||
*
|
||||
* It makes a {@link OrderElement} from a {@link ImportTask}
|
||||
*
|
||||
* @param task
|
||||
* ImportTask to extract data from.
|
||||
* @param orderVersion
|
||||
* Number of version.
|
||||
* @return OrderElement OrderElement that represent the data.
|
||||
*/
|
||||
private OrderElement convertImportTaskToOrderElement(
|
||||
OrderVersion orderVersion, ImportTask task) {
|
||||
|
||||
Validate.notNull(orderVersion);
|
||||
OrderElement orderElement;
|
||||
String code;
|
||||
|
||||
if (task.children.size() == 0) {
|
||||
code = getCode(EntityNameEnum.ORDER);
|
||||
|
||||
orderElement = OrderLine.createUnvalidatedWithUnfixedPercentage(
|
||||
code, 0);
|
||||
|
||||
if (!orderElement.getHoursGroups().isEmpty()) {
|
||||
orderElement.getHoursGroups().get(0)
|
||||
.setCode(UUID.randomUUID().toString());
|
||||
}
|
||||
|
||||
} else {
|
||||
code = getCode(EntityNameEnum.ORDER);
|
||||
orderElement = OrderLineGroup.createUnvalidated(code);
|
||||
orderElement.useSchedulingDataFor(orderVersion);
|
||||
}
|
||||
|
||||
List<OrderElement> children = new ArrayList<OrderElement>();
|
||||
|
||||
for (ImportTask childrenTask : task.children) {
|
||||
children.add(convertImportTaskToOrderElement(orderVersion,
|
||||
childrenTask));
|
||||
}
|
||||
|
||||
for (OrderElement child : children) {
|
||||
|
||||
((OrderLineGroup) orderElement).add(child);
|
||||
}
|
||||
|
||||
orderElement.setName(task.name);
|
||||
orderElement.setCode(code);
|
||||
orderElement.setInitDate(new Date());
|
||||
|
||||
return orderElement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves an {@link Order} which has all the data that we want to store in
|
||||
* the database.
|
||||
*
|
||||
* @param Order
|
||||
* Order with the data.
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public void storeOrder(final Order order) {
|
||||
|
||||
orderDAO.save(order);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
6
pom.xml
6
pom.xml
|
|
@ -755,6 +755,12 @@
|
|||
<artifactId>jqplot4java</artifactId>
|
||||
<version>1.2.3-javascript</version>
|
||||
</dependency>
|
||||
<!-- MPXJ Library -->
|
||||
<dependency>
|
||||
<groupId>net.sourceforge</groupId>
|
||||
<artifactId>mpxj</artifactId>
|
||||
<version>4.3.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue