Java tutorial
/** * Projet CHOUETTE * * ce projet est sous license libre * voir LICENSE.txt pour plus de details * */ package fr.certu.chouette.gui.command; // import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Method; import java.math.BigDecimal; import java.sql.Time; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.MissingResourceException; import java.util.ResourceBundle; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; import org.apache.log4j.Logger; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.orm.hibernate3.SessionFactoryUtils; import org.springframework.orm.hibernate3.SessionHolder; import org.springframework.transaction.support.TransactionSynchronizationManager; import fr.certu.chouette.common.ChouetteException; import fr.certu.chouette.dao.IDaoTemplate; import fr.certu.chouette.filter.Filter; import fr.certu.chouette.filter.FilterOrder; import fr.certu.chouette.manager.INeptuneManager; import fr.certu.chouette.model.neptune.AreaCentroid; import fr.certu.chouette.model.neptune.Line; import fr.certu.chouette.model.neptune.NeptuneIdentifiedObject; import fr.certu.chouette.model.neptune.Route; import fr.certu.chouette.model.neptune.StopArea; import fr.certu.chouette.model.neptune.StopPoint; import fr.certu.chouette.plugin.exchange.FormatDescription; import fr.certu.chouette.plugin.exchange.ListParameterValue; import fr.certu.chouette.plugin.exchange.ParameterDescription; import fr.certu.chouette.plugin.exchange.ParameterValue; import fr.certu.chouette.plugin.exchange.SimpleParameterValue; import fr.certu.chouette.plugin.exchange.report.ExchangeReport; import fr.certu.chouette.plugin.model.ExportLogMessage; import fr.certu.chouette.plugin.model.FileValidationLogMessage; import fr.certu.chouette.plugin.model.GuiExport; import fr.certu.chouette.plugin.model.GuiFileValidation; import fr.certu.chouette.plugin.model.GuiImport; import fr.certu.chouette.plugin.model.ImportLogMessage; import fr.certu.chouette.plugin.model.Organisation; import fr.certu.chouette.plugin.model.Referential; import fr.certu.chouette.plugin.report.Report; import fr.certu.chouette.plugin.report.ReportHolder; import fr.certu.chouette.plugin.report.ReportItem; import fr.certu.chouette.plugin.validation.ValidationParameters; import fr.certu.chouette.service.geographic.IGeographicService; /** * * * import command : ( -fileFormat utilis si l'extension du fichier n'est pas reprsentative du format) * -c import -o line -format XXX -inputFile YYYY [-fileFormat TTT] -importId ZZZ ... * * export command : * selected objects * -c export -o line -format XXX -outputFile YYYY -exportId ZZZ -id list_of_id_separated_by_commas ... * all objects * -c export -o line -format XXX -outputFile YYYY -exportId ZZZ * dependency criteria : sample for all lines of one network * -c export -o network -format XXX -outputFile YYYY -exportId ZZZ -id list_of_network_id_separated_by_commas * * validate command : * from neptune file : * -c validate -o line -inputFile YYYY [-fileFormat TTT] -validationId ZZZ * * from database : * -c validate -o line|network|company -validationId ZZZ [-id list_of_ids_separated_by_commas] * */ @NoArgsConstructor public class Command { private static final Logger logger = Logger.getLogger(Command.class); public static ClassPathXmlApplicationContext applicationContext; /** * */ public static void printHelp() { ResourceBundle bundle = null; try { bundle = ResourceBundle.getBundle(Command.class.getName(), locale); } catch (MissingResourceException e1) { try { bundle = ResourceBundle.getBundle(Command.class.getName()); } catch (MissingResourceException e2) { System.out.println("missing help resource"); return; } } printBloc(bundle, "Header", ""); printBloc(bundle, "Option", " "); System.out.println(""); String[] commands = getHelpString(bundle, "Commands").split(" "); for (String command : commands) { printCommandDetail(bundle, command, " "); System.out.println(""); } printBloc(bundle, "Footer", ""); } @Getter @Setter private Map<String, INeptuneManager<NeptuneIdentifiedObject>> managers; @Setter private ValidationParameters validationParameters; @Setter private IDaoTemplate<Organisation> organisationDao;; @Setter private IDaoTemplate<Referential> referentialDao;; @Setter private IDaoTemplate<GuiImport> importDao;; @Setter private IDaoTemplate<ImportLogMessage> importLogMessageDao;; @Setter private IDaoTemplate<GuiExport> exportDao; @Setter private IDaoTemplate<ExportLogMessage> exportLogMessageDao; @Setter private IDaoTemplate<GuiFileValidation> fileValidationDao; @Setter private IDaoTemplate<FileValidationLogMessage> fileValidationLogMessageDao; @Setter private IGeographicService geographicService; private static String getHelpString(ResourceBundle bundle, String key) { try { return bundle.getString(key); } catch (Exception e) { return null; } } private static void printBloc(ResourceBundle bundle, String key, String indent) { // print options String line = null; int rank = 1; do { line = getHelpString(bundle, key + rank); if (line != null) { System.out.println(indent + line); printBloc(bundle, key + rank + "_", indent + " "); } rank++; } while (line != null); } private static void printCommandDetail(ResourceBundle bundle, String key, String indent) { // print command String line = getHelpString(bundle, key); if (line == null) { System.out.println("-- unknown command : " + key); return; } System.out.println(indent + line); printBloc(bundle, key + "_", indent + " "); line = getHelpString(bundle, key + "_n"); if (line != null) { System.out.println(indent + " " + line); } } /** * */ private static void printCommandDetail(String command) { ResourceBundle bundle = null; try { bundle = ResourceBundle.getBundle(Command.class.getName(), locale); } catch (MissingResourceException e1) { try { bundle = ResourceBundle.getBundle(Command.class.getName()); } catch (MissingResourceException e2) { System.out.println("missing help resource"); return; } } String lowerCommand = command.toLowerCase(); printCommandDetail(bundle, lowerCommand, " "); } /** * */ private static void printCommandSyntax(boolean interactive) { ResourceBundle bundle = null; try { bundle = ResourceBundle.getBundle(Command.class.getName(), locale); } catch (MissingResourceException e1) { try { bundle = ResourceBundle.getBundle(Command.class.getName()); } catch (MissingResourceException e2) { System.out.println("missing help resource"); return; } } String[] commands = getHelpString(bundle, "Commands").split(" "); if (interactive) { for (String command : commands) { String line = getHelpString(bundle, command); System.out.println(" " + line); } } else { for (String command : commands) { printCommandDetail(bundle, command, " "); System.out.println(""); } } } public Map<String, List<String>> globals = new HashMap<String, List<String>>(); public static Map<String, String> shortCuts; public boolean verbose = false; public static Locale locale = Locale.getDefault(); static { shortCuts = new HashMap<String, String>(); shortCuts.put("c", "command"); shortCuts.put("h", "help"); shortCuts.put("o", "object"); shortCuts.put("v", "verbose"); } /** * @param factory */ public static void closeDao() { ConfigurableBeanFactory factory = applicationContext.getBeanFactory(); SessionFactory sessionFactory = (SessionFactory) factory.getBean("sessionFactory"); SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager .unbindResource(sessionFactory); SessionFactoryUtils.closeSession(sessionHolder.getSession()); } /** * @param factory */ public static void initDao() { ConfigurableBeanFactory factory = applicationContext.getBeanFactory(); SessionFactory sessionFactory = (SessionFactory) factory.getBean("sessionFactory"); Session session = SessionFactoryUtils.getSession(sessionFactory, true); TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session)); } /** * @param args */ public static void main(String[] args) { // pattern partially work String[] context = { "classpath*:/chouetteContext.xml" }; if (args.length >= 1) { if (args[0].equalsIgnoreCase("-help") || args[0].equalsIgnoreCase("-h")) { printHelp(); System.exit(0); } applicationContext = new ClassPathXmlApplicationContext(context); ConfigurableBeanFactory factory = applicationContext.getBeanFactory(); Command command = (Command) factory.getBean("Command"); initDao(); command.execute(args); closeDao(); System.runFinalization(); } else { printHelp(); } } /** * @param args */ public void execute(String[] args) { List<CommandArgument> commands = null; try { commands = parseArgs(args); } catch (Exception e1) { if (getBoolean(globals, "help")) { printHelp(); return; } else { System.err.println("invalid syntax : " + e1.getMessage()); logger.error(e1.getMessage(), e1); System.exit(1); } } if (getBoolean(globals, "help")) { printHelp(); return; } if (getBoolean(globals, "verbose")) { verbose = true; for (String key : globals.keySet()) { System.out .println("global parameters " + key + " : " + Arrays.toString(globals.get(key).toArray())); } } for (String key : globals.keySet()) { logger.info("global parameters " + key + " : " + Arrays.toString(globals.get(key).toArray())); } int commandNumber = 0; try { for (CommandArgument command : commands) { commandNumber++; executeCommand(commandNumber, command); } } catch (Exception e) { if (getBoolean(globals, "help")) { printHelp(); } else { System.out.println("command failed : " + e.getMessage()); logger.error(e.getMessage(), e); System.exit(1); } } } /** * @param beans * @param commandNumber * @param command * @return * @throws ChouetteException * @throws Exception */ public void executeCommand(int commandNumber, CommandArgument command) throws Exception { String name = command.getName(); Map<String, List<String>> parameters = command.getParameters(); if (verbose) { traceCommand(commandNumber, name, parameters); } logger.info("Command " + commandNumber + " : " + name); for (String key : parameters.keySet()) { logger.info(" parameters " + key + " : " + Arrays.toString(parameters.get(key).toArray())); } if (name.equals("verbose")) { verbose = !(getBoolean(parameters, "off")); return; } if (name.equals("help")) { String cmd = getSimpleString(parameters, "cmd", ""); if (cmd.length() > 0) { printCommandDetail(cmd); } else { printCommandSyntax(true); } return; } if (name.equals("lang")) { if (getBoolean(parameters, "en")) { locale = Locale.ENGLISH; } else if (getBoolean(parameters, "fr")) { locale = Locale.FRENCH; } else { System.out.println(locale); } return; } INeptuneManager<NeptuneIdentifiedObject> manager = getManager(parameters); long tdeb = System.currentTimeMillis(); if (name.equals("import")) { int code = executeImport(manager, parameters); if (code > 0) { logger.error(" command failed with code " + code); System.exit(code); } } else if (name.equals("validate")) { int code = executeValidate(manager, parameters); if (code > 0) { logger.error(" command failed with code " + code); System.exit(code); } } else if (name.equals("export")) { int code = executeExport(manager, parameters); if (code > 0) { logger.error(" command failed with code " + code); System.exit(code); } } else if (name.equals("exportForDeletion")) { int code = executeExportDeletion(manager, parameters); if (code > 0) { logger.error(" command failed with code " + code); System.exit(code); } } else { throw new Exception("Command " + commandNumber + ": unknown command :" + command.getName()); } long tfin = System.currentTimeMillis(); if (verbose) { System.out.println("command " + command.getName() + " executed in " + getTimeAsString(tfin - tdeb)); } logger.info(" command " + command.getName() + " executed in " + getTimeAsString(tfin - tdeb)); return; } /** * export command : * selected objects * -c export -o line -format XXX -outputFile YYYY -exportId ZZZ -id list_of_id_separated_by_commas ... * all objects * -c export -o line -format XXX -outputFile YYYY -exportId ZZZ * dependency criteria : sample for all lines of one network * -c export -o network -format XXX -outputFile YYYY -exportId ZZZ -id list_of_network_id_separated_by_commas * * @param manager * @param parameters * @return */ private int executeExport(INeptuneManager<NeptuneIdentifiedObject> manager, Map<String, List<String>> parameters) { String format = getSimpleString(parameters, "format"); Long exportId = Long.valueOf(getSimpleString(parameters, "exportid")); if (!exportDao.exists(exportId)) { // error export not found logger.error("export not found " + exportId); return 1; } GuiExport guiExport = exportDao.get(exportId); logger.info("Export data for export id " + exportId); logger.info(" type : " + guiExport.getType()); logger.info(" options : " + guiExport.getOptions()); logger.info(" references type : " + guiExport.getReferencesType()); logger.info(" reference ids : " + guiExport.getReferenceIds()); Referential referential = referentialDao.get(guiExport.getReferentialId()); logger.info("Referential " + guiExport.getReferentialId()); logger.info(" name : " + referential.getName()); logger.info(" slug : " + referential.getSlug()); logger.info(" projection type : " + referential.getProjectionType()); String projectionType = null; if (referential.getProjectionType() != null && !referential.getProjectionType().isEmpty()) { logger.info(" projection type for export: " + referential.getProjectionType()); projectionType = referential.getProjectionType(); } // set projection for export (inactive if not set) geographicService.switchProjection(projectionType); List<Report> reports = new ArrayList<Report>(); String[] ids = new String[0]; if (parameters.containsKey("id")) ids = getSimpleString(parameters, "id").split(","); try { List<FormatDescription> formats = manager.getExportFormats(null); FormatDescription description = null; for (FormatDescription formatDescription : formats) { if (formatDescription.getName().equalsIgnoreCase(format)) { description = formatDescription; break; } } if (description == null) { String objectName = getActiveObject(parameters); List<String> objects = parameters.get("object"); objects.clear(); objects.add("line"); manager = getManager(parameters); parameters.remove("id"); List<String> filter = new ArrayList<String>(); if (objectName.equals("network")) { filter.add("ptNetwork.id"); } else if (objectName.equals("company")) { filter.add("company.id"); } else { throw new IllegalArgumentException("format " + format + " unavailable for " + objectName); } if (ids != null && ids.length > 0) { filter.add("in"); filter.addAll(Arrays.asList(ids)); parameters.put("filter", filter); } return executeExport(manager, parameters); } List<ParameterValue> values = populateParameters(description, parameters); ReportHolder holder = new ReportHolder(); List<NeptuneIdentifiedObject> beans = executeGet(manager, parameters); manager.doExport(null, beans, format, values, holder); if (holder.getReport() != null) { Report r = holder.getReport(); reports.add(r); } } catch (Exception e) { logger.error("export failed " + e.getMessage(), e); GuiReport errorReport = new GuiReport("EXPORT_ERROR", Report.STATE.ERROR); GuiReportItem item = new GuiReportItem("EXCEPTION", Report.STATE.ERROR, e.getMessage()); errorReport.addItem(item); reports.add(errorReport); saveExportReports(exportId, format, reports); return 1; } saveExportReports(exportId, format, reports); return 0; } /** * @param beans * @param manager * @param parameters * @return */ private int executeExportDeletion(INeptuneManager<NeptuneIdentifiedObject> manager, Map<String, List<String>> parameters) { List<NeptuneIdentifiedObject> beans = new ArrayList<NeptuneIdentifiedObject>(); String format = getSimpleString(parameters, "format"); try { List<FormatDescription> formats = manager.getDeleteExportFormats(null); FormatDescription description = null; for (FormatDescription formatDescription : formats) { if (formatDescription.getName().equalsIgnoreCase(format)) { description = formatDescription; break; } } if (description == null) { throw new IllegalArgumentException( "format " + format + " unavailable, check command getDeletionExportFormats for list "); } List<ParameterValue> values = new ArrayList<ParameterValue>(); for (ParameterDescription desc : description.getParameterDescriptions()) { String name = desc.getName(); String key = name.toLowerCase(); List<String> vals = parameters.get(key); if (vals == null) { if (desc.isMandatory()) { throw new IllegalArgumentException("parameter -" + name + " is required, check command getDeletionExportFormats for list "); } } else { if (desc.isCollection()) { ListParameterValue val = new ListParameterValue(name); switch (desc.getType()) { case FILEPATH: val.setFilepathList(vals); break; case STRING: val.setStringList(vals); break; case FILENAME: val.setFilenameList(vals); break; default: throw new IllegalArgumentException( "parameter -" + name + " unknown type " + desc.getType()); } values.add(val); } else { if (vals.size() != 1) { throw new IllegalArgumentException("parameter -" + name + " must be unique, check command getDeletionExportFormats for list "); } String simpleval = vals.get(0); SimpleParameterValue val = new SimpleParameterValue(name); switch (desc.getType()) { case FILEPATH: val.setFilepathValue(simpleval); break; case STRING: val.setStringValue(simpleval); break; case FILENAME: val.setFilenameValue(simpleval); break; case BOOLEAN: val.setBooleanValue(Boolean.parseBoolean(simpleval)); break; case INTEGER: val.setIntegerValue(Long.parseLong(simpleval)); break; default: throw new IllegalArgumentException( "parameter -" + name + " unknown type " + desc.getType()); } values.add(val); } } } ReportHolder holder = new ReportHolder(); manager.doExportDeleted(null, beans, format, values, holder); if (holder.getReport() != null) { Report r = holder.getReport(); System.out.println(r.getLocalizedMessage()); // printItems(System.out,"",r.getItems()); } } catch (ChouetteException e) { logger.error(e.getMessage()); Throwable caused = e.getCause(); while (caused != null) { logger.error("caused by " + caused.getMessage()); caused = caused.getCause(); } throw new RuntimeException("export failed, see details in log"); } return 0; } /** * @param manager * @param parameters * @return * @throws ChouetteException */ private List<NeptuneIdentifiedObject> executeGet(INeptuneManager<NeptuneIdentifiedObject> manager, Map<String, List<String>> parameters) throws ChouetteException { Filter filter = null; if (parameters.containsKey("id")) { String[] sids = getSimpleString(parameters, "id").split(","); List<Long> ids = new ArrayList<Long>(); for (String id : sids) { ids.add(Long.valueOf(id)); } filter = Filter.getNewInFilter("id", ids); } else if (parameters.containsKey("objectid")) { List<String> sids = parameters.get("objectid"); filter = Filter.getNewInFilter("objectId", sids); } else if (parameters.containsKey("filter")) { List<String> filterArgs = parameters.get("filter"); if (filterArgs.size() < 2) { throw new IllegalArgumentException("invalid syntax for filter "); } String filterKey = filterArgs.get(0); String filterOp = filterArgs.get(1); if (filterArgs.size() == 2) { if (filterOp.equalsIgnoreCase("null") || filterOp.equalsIgnoreCase("isnull")) { filter = Filter.getNewIsNullFilter(filterKey); } else { throw new IllegalArgumentException(filterOp + " : invalid syntax or not yet implemented"); } } else if (filterOp.equalsIgnoreCase("in")) { if (filterKey.endsWith(".id")) { List<String> values = filterArgs.subList(2, filterArgs.size()); List<Long> ids = new ArrayList<Long>(); for (String id : values) { ids.add(Long.valueOf(id)); } filter = Filter.getNewInFilter(filterKey, ids); } else { List<String> values = filterArgs.subList(2, filterArgs.size()); filter = Filter.getNewInFilter(filterKey, values); } } else if (filterArgs.size() == 3) { String value = filterArgs.get(2); if (filterOp.equalsIgnoreCase("eq") || filterOp.equals("=")) { filter = Filter.getNewEqualsFilter(filterKey, value); } else if (filterOp.equalsIgnoreCase("like")) { filter = Filter.getNewLikeFilter(filterKey, value); } else { throw new IllegalArgumentException(filterOp + " : invalid syntax or not yet implemented"); } } else { throw new IllegalArgumentException(filterOp + " : invalid syntax or not yet implemented"); } } else { filter = Filter.getNewEmptyFilter(); } if (parameters.containsKey("orderby")) { List<String> orderFields = parameters.get("orderby"); boolean desc = getBoolean(parameters, "desc"); if (desc) { for (String field : orderFields) { filter.addOrder(FilterOrder.desc(field)); } } else { for (String field : orderFields) { filter.addOrder(FilterOrder.asc(field)); } } } String limit = getSimpleString(parameters, "limit", "none"); if (!limit.equalsIgnoreCase("none")) { filter.addLimit(Integer.parseInt(limit)); } List<NeptuneIdentifiedObject> beans = manager.getAll(null, filter); if (verbose) { int count = 0; for (NeptuneIdentifiedObject bean : beans) { if (count > 10) { System.out.println(" ... "); break; } count++; System.out.println(bean.getName() + " : ObjectId = " + bean.getObjectId()); } } System.out.println("beans count = " + beans.size()); return beans; } /** * import command : ( -fileFormat utilis si l'extension du fichier n'est pas reprsentative du format) * -c import -o line -format XXX -inputFile YYYY [-fileFormat TTT] -importId ZZZ ... * @param manager * @param parameters * @return */ private int executeImport(INeptuneManager<NeptuneIdentifiedObject> manager, Map<String, List<String>> parameters) { parameters.put("reportforsave", Arrays.asList(new String[] { "true" })); // parameters.put("validate",Arrays.asList(new String[]{"true"})); // force validation if possible GuiReport saveReport = new GuiReport("SAVE", Report.STATE.OK); Report importReport = null; List<Report> reports = new ArrayList<Report>(); // check if import exists and accept unzip before call String format = getSimpleString(parameters, "format"); String inputFile = getSimpleString(parameters, "inputfile"); // String fileFormat = getSimpleString(parameters,"fileformat",""); Long importId = Long.valueOf(getSimpleString(parameters, "importid")); if (!importDao.exists(importId)) { // error import not found logger.error("import not found " + importId); return 1; } GuiImport guiImport = importDao.get(importId); logger.info("Export data for export id " + importId); logger.info(" type : " + guiImport.getType()); logger.info(" options : " + guiImport.getOptions()); Referential referential = referentialDao.get(guiImport.getReferentialId()); logger.info("Referential " + guiImport.getReferentialId()); logger.info(" name : " + referential.getName()); logger.info(" slug : " + referential.getSlug()); logger.info(" projection type : " + referential.getProjectionType()); String projectionType = null; if (referential.getProjectionType() != null && !referential.getProjectionType().isEmpty()) { logger.info(" projection type for export: " + referential.getProjectionType()); projectionType = referential.getProjectionType(); parameters.put("srid", Arrays.asList(new String[] { projectionType })); } // set projection for import (inactive if not set) geographicService.switchProjection(projectionType); int beanCount = 0; boolean zipped = (inputFile.toLowerCase().endsWith(".zip")); try { List<FormatDescription> formats = manager.getImportFormats(null); FormatDescription description = null; for (FormatDescription formatDescription : formats) { if (formatDescription.getName().equalsIgnoreCase(format)) { description = formatDescription; break; } } if (description == null) { throw new IllegalArgumentException("format " + format + " unavailable"); } List<String> suffixes = new ArrayList<String>(); for (ParameterDescription desc : description.getParameterDescriptions()) { if (desc.getName().equalsIgnoreCase("inputfile")) { suffixes = desc.getAllowedExtensions(); break; } } List<ParameterValue> values = populateParameters(description, parameters, "inputfile", "fileformat"); if (zipped && description.isUnzipAllowed()) { SimpleParameterValue inputFileParam = new SimpleParameterValue("inputFile"); values.add(inputFileParam); // unzip files , import and save contents ZipFile zip = null; File temp = null; File tempRep = new File(FileUtils.getTempDirectory(), "massImport" + importId); if (!tempRep.exists()) tempRep.mkdirs(); try { zip = new ZipFile(inputFile); for (Enumeration<? extends ZipEntry> entries = zip.entries(); entries.hasMoreElements();) { ZipEntry entry = entries.nextElement(); if (entry.isDirectory()) { File dir = new File(tempRep, entry.getName()); dir.mkdirs(); continue; } if (!FilenameUtils.isExtension(entry.getName().toLowerCase(), suffixes)) { logger.error("entry " + entry.getName() + " ignored, unknown extension"); continue; } InputStream stream = null; try { stream = zip.getInputStream(entry); } catch (IOException e) { logger.error("entry " + entry.getName() + " cannot read"); continue; } byte[] bytes = new byte[4096]; int len = stream.read(bytes); temp = new File(tempRep, entry.getName()); FileOutputStream fos = new FileOutputStream(temp); while (len > 0) { fos.write(bytes, 0, len); len = stream.read(bytes); } fos.close(); // import if (verbose) System.out.println("import file " + entry.getName()); logger.info("import file " + entry.getName()); inputFileParam.setFilepathValue(temp.getAbsolutePath()); ReportHolder holder = new ReportHolder(); List<NeptuneIdentifiedObject> beans = manager.doImport(null, format, values, holder); if (holder.getReport() != null) { if (importReport == null) { importReport = holder.getReport(); reports.add(importReport); } else { importReport.addAll(holder.getReport().getItems()); } } // save if (beans != null && !beans.isEmpty()) { for (NeptuneIdentifiedObject bean : beans) { if (verbose) { System.out.println("save " + bean.getName() + " (" + bean.getObjectId() + ")"); } logger.info("save " + bean.getName() + " (" + bean.getObjectId() + ")"); // check all stopareas if (bean instanceof Line) { Line line = (Line) bean; checkProjection(line); } } try { manager.saveAll(null, beans, true, true); for (NeptuneIdentifiedObject bean : beans) { GuiReportItem item = new GuiReportItem("SAVE_OK", Report.STATE.OK, bean.getName()); importReport.addItem(item); beanCount++; } } catch (Exception e) { logger.error("fail to save data :" + e.getMessage(), e); for (NeptuneIdentifiedObject bean : beans) { GuiReportItem item = new GuiReportItem("SAVE_ERROR", Report.STATE.ERROR, bean.getName(), filter_chars(e.getMessage())); importReport.addItem(item); } } } temp.delete(); } try { zip.close(); } catch (IOException e) { logger.info("cannot close zip file"); } } catch (IOException e) { //reports.add(saveReport); System.out.println("import failed " + e.getMessage()); logger.error("import failed " + e.getMessage(), e); saveImportReports(importId, format, reports); return 1; } finally { try { FileUtils.deleteDirectory(tempRep); } catch (IOException e) { logger.warn("temporary directory " + tempRep.getAbsolutePath() + " could not be deleted"); } } } else { SimpleParameterValue inputFileParam = new SimpleParameterValue("inputFile"); inputFileParam.setFilepathValue(inputFile); values.add(inputFileParam); // if (!fileFormat.isEmpty()) // { // SimpleParameterValue fileFormatParam = new SimpleParameterValue("fileFormat"); // fileFormatParam.setStringValue(fileFormat); // values.add(fileFormatParam); // } // surround with try catch ReportHolder holder = new ReportHolder(); List<NeptuneIdentifiedObject> beans = manager.doImport(null, format, values, holder); if (holder.getReport() != null) { importReport = holder.getReport(); reports.add(holder.getReport()); } logger.info("imported Lines " + beans.size()); for (NeptuneIdentifiedObject bean : beans) { if (bean instanceof Line) { Line line = (Line) bean; checkProjection(line); } List<NeptuneIdentifiedObject> oneBean = new ArrayList<NeptuneIdentifiedObject>(); oneBean.add(bean); try { logger.info("save Line " + bean.getName()); manager.saveAll(null, oneBean, true, true); GuiReportItem item = new GuiReportItem("SAVE_OK", Report.STATE.OK, bean.getName()); saveReport.addItem(item); beanCount++; } catch (Exception e) { logger.error("save failed " + e.getMessage(), e); GuiReportItem item = new GuiReportItem("SAVE_ERROR", Report.STATE.ERROR, bean.getName(), e.getMessage()); saveReport.addItem(item); } } } } catch (Exception e) { // fill report with error if (saveReport.getItems() != null && !saveReport.getItems().isEmpty()) reports.add(saveReport); String msg = e.getMessage(); if (msg == null) msg = e.getClass().getName(); System.out.println("import failed " + msg); logger.error("import failed " + msg, e); GuiReport errorReport = new GuiReport("IMPORT_ERROR", Report.STATE.ERROR); GuiReportItem item = new GuiReportItem("EXCEPTION", Report.STATE.ERROR, msg); errorReport.addItem(item); reports.add(errorReport); saveImportReports(importId, format, reports); return 1; } if (saveReport.getItems() != null && !saveReport.getItems().isEmpty()) reports.add(saveReport); saveImportReports(importId, format, reports); return (beanCount == 0 ? 1 : 0); } private Object filter_chars(String message) { if (message == null) return ""; return message.replaceAll("\t", "").replaceAll("\"", "'"); } private void checkProjection(Line line) { for (Route route : line.getRoutes()) { for (StopPoint point : route.getStopPoints()) { checkProjection(point.getContainedInStopArea()); } } } private void checkProjection(StopArea area) { if (area == null) return; if (area.getAreaCentroid() != null) { AreaCentroid centroid = area.getAreaCentroid(); if (centroid.getLongLatType() == null) { geographicService.convertToWGS84(area); } } checkProjection(area.getParent()); } /** * @param parameters */ private void executeSetValidationParameters(Map<String, List<String>> parameters) { for (String key : parameters.keySet()) { if (key.toLowerCase().startsWith("test") || key.toLowerCase().startsWith("projection")) { String value = ""; try { value = getSimpleString(parameters, key); } catch (Exception ex) { List<String> values = parameters.get(key); for (String item : values) { value += item + " "; } } if (validationParameters == null) validationParameters = new ValidationParameters(); try { setAttribute(validationParameters, key, value); } catch (Exception e) { logger.error(e.getMessage()); System.err.println("unknown or unvalid parameter " + key); } } } } /** * validate command : * from neptune file : * -c validate -o line -inputFile YYYY [-fileFormat TTT] -validateId ZZZ * * from database : * -c validate -o line|network|company -validateId ZZZ [-id list_of_ids_separated_by_commas] * * @param manager * @param parameters * @return * @throws ChouetteException */ private int executeValidate(INeptuneManager<NeptuneIdentifiedObject> manager, Map<String, List<String>> parameters) throws ChouetteException { Long validationId = Long.valueOf(getSimpleString(parameters, "validationid")); List<NeptuneIdentifiedObject> beans = new ArrayList<NeptuneIdentifiedObject>(); String inputFile = getSimpleString(parameters, "inputfile", ""); ReportHolder holder = new ReportHolder(); if (!inputFile.isEmpty()) { parameters.put("validate", Arrays.asList(new String[] { "true" })); beans = neptuneImport(manager, parameters, holder); } else { beans = executeGet(manager, parameters); } Report valReport = null; if (beans != null && !beans.isEmpty()) { executeSetValidationParameters(parameters); valReport = manager.validate(null, beans, validationParameters); } // merge reports if (holder.getReport() != null) { Report importReport = holder.getReport(); saveFileValidationReport(validationId, importReport); } // save report if (valReport != null) { for (ReportItem item : valReport.getItems()) { saveFileValidationReport(validationId, item); } } return 0; } /** * @param parameters * @return */ private String getActiveObject(Map<String, List<String>> parameters) { String object = null; try { object = getSimpleString(parameters, "object").toLowerCase(); } catch (IllegalArgumentException e) { object = getSimpleString(globals, "object", "xxx").toLowerCase(); } if (!managers.containsKey(object)) { return "unknown object"; } return object; } /** * @param string * @return */ public boolean getBoolean(Map<String, List<String>> parameters, String key) { List<String> values = parameters.get(key); if (values == null) return false; if (values.size() > 1) throw new IllegalArgumentException("parameter -" + key + " of boolean type must be unique"); return Boolean.parseBoolean(values.get(0)); } /** * @param parameters * @return */ public INeptuneManager<NeptuneIdentifiedObject> getManager(Map<String, List<String>> parameters) { String object = null; try { object = getSimpleString(parameters, "object").toLowerCase(); List<String> objects = new ArrayList<String>(); objects.add(object); globals.put("object", objects); } catch (IllegalArgumentException e) { object = getSimpleString(globals, "object").toLowerCase(); } INeptuneManager<NeptuneIdentifiedObject> manager = managers.get(object); if (manager == null) { throw new IllegalArgumentException("unknown object " + object + ", only " + Arrays.toString(managers.keySet().toArray()) + " are managed"); } return manager; } /** * @param string * @return */ public String getSimpleString(Map<String, List<String>> parameters, String key) { List<String> values = parameters.get(key); if (values == null) throw new IllegalArgumentException("parameter -" + key + " of String type is required"); if (values.size() > 1) throw new IllegalArgumentException("parameter -" + key + " of String type must be unique"); return values.get(0); } /** * @param string * @return */ public String getSimpleString(Map<String, List<String>> parameters, String key, String defaultValue) { List<String> values = parameters.get(key); if (values == null) return defaultValue; if (values.size() > 1) throw new IllegalArgumentException("parameter -" + key + " of String type must be unique"); return values.get(0); } /** * convert a duration in millisecond to literal * * the returned format depends on the duration : * <br>if duration > 1 hour, format is HH h MM m SS s * <br>else if duration > 1 minute , format is MM m SS s * <br>else if duration > 1 second , format is SS s * <br>else (duration < 1 second) format is LLL ms * * @param duration the duration to convert * @return the duration */ private String getTimeAsString(long duration) { long d = duration; long milli = d % 1000; d /= 1000; long sec = d % 60; d /= 60; long min = d % 60; d /= 60; long hour = d; String res = ""; if (hour > 0) res += hour + " h " + min + " m " + sec + " s "; else if (min > 0) res += min + " m " + sec + " s "; else if (sec > 0) res += sec + " s "; res += milli + " ms"; return res; } private List<NeptuneIdentifiedObject> neptuneImport(INeptuneManager<NeptuneIdentifiedObject> manager, Map<String, List<String>> parameters, ReportHolder holder) throws ChouetteException { String format = "NEPTUNE"; List<FormatDescription> formats = manager.getImportFormats(null); FormatDescription description = null; for (FormatDescription formatDescription : formats) { if (formatDescription.getName().equalsIgnoreCase(format)) { description = formatDescription; break; } } if (description == null) { throw new IllegalArgumentException("format " + format + " unavailable"); } List<ParameterValue> values = populateParameters(description, parameters); List<NeptuneIdentifiedObject> beans = manager.doImport(null, format, values, holder); return beans; } private List<CommandArgument> parseArgs(String[] args) throws Exception { Map<String, List<String>> parameters = globals; List<CommandArgument> commands = new ArrayList<CommandArgument>(); CommandArgument command = null; if (args.length == 0) { List<String> list = new ArrayList<String>(); list.add("true"); parameters.put("help", list); } for (int i = 0; i < args.length; i++) { if (isOption(args[i])) { String key = args[i].substring(1).toLowerCase(); if (key.length() == 1) { String alias = shortCuts.get(key); if (alias != null) key = alias; } if (key.equals("command")) { if (i == args.length - 1) { throw new Exception("missing command name"); } String name = args[++i]; if (name.startsWith("-")) { throw new Exception("missing command name before " + name); } command = new CommandArgument(name); parameters = command.getParameters(); commands.add(command); } else { if (parameters.containsKey(key)) { throw new Exception("duplicate parameter : -" + key); } List<String> list = new ArrayList<String>(); if (i == args.length - 1 || isOption(args[i + 1])) { list.add("true"); } else { while ((i + 1) < args.length && !isOption(args[i + 1])) { list.add(args[++i]); } } parameters.put(key, list); } } } return commands; } private boolean isOption(String arg) { if (arg.length() < 2) return false; return arg.startsWith("-") && !Character.isDigit(arg.charAt(1)); } private List<ParameterValue> populateParameters(FormatDescription description, Map<String, List<String>> parameters, String... excluded) { List<ParameterValue> values = new ArrayList<ParameterValue>(); List<String> excludedParams = Arrays.asList(excluded); for (ParameterDescription desc : description.getParameterDescriptions()) { String name = desc.getName(); String key = name.toLowerCase(); if (excludedParams.contains(key)) continue; List<String> vals = parameters.get(key); if (vals == null) { if (desc.isMandatory()) { throw new IllegalArgumentException("parameter -" + name + " is required"); } } else { if (desc.isCollection()) { ListParameterValue val = new ListParameterValue(name); switch (desc.getType()) { case FILEPATH: val.setFilepathList(vals); break; case STRING: val.setStringList(vals); break; case FILENAME: val.setFilenameList(vals); break; default: throw new IllegalArgumentException( "parameter -" + name + " unknown type " + desc.getType()); } values.add(val); logger.debug("prepare list parameter " + name); } else { if (vals.size() != 1) { throw new IllegalArgumentException("parameter -" + name + " must be unique"); } String simpleval = vals.get(0); SimpleParameterValue val = new SimpleParameterValue(name); switch (desc.getType()) { case FILEPATH: val.setFilepathValue(simpleval); break; case STRING: val.setStringValue(simpleval); break; case FILENAME: val.setFilenameValue(simpleval); break; case BOOLEAN: val.setBooleanValue(Boolean.parseBoolean(simpleval)); break; case INTEGER: val.setIntegerValue(Long.parseLong(simpleval)); break; case DATE: val.setDateValue(toCalendar(simpleval)); break; } values.add(val); logger.debug("prepare simple parameter " + name); } } } return values; } private int saveExportReport(Long exportId, String format, Report report, int position) { String prefix = report.getOriginKey(); if (prefix == null || report instanceof ReportItem) prefix = ((ReportItem) report).getMessageKey(); prefix = format + prefix; ExportLogMessage message = new ExportLogMessage(exportId, format, report, position++); exportLogMessageDao.save(message); if (report.getItems() != null) { for (ReportItem item : report.getItems()) { position = saveExportReportItem(exportId, format, item, prefix, position); } } return position; } private int saveExportReportItem(Long exportId, String format, ReportItem item, String prefix, int position) { ExportLogMessage message = new ExportLogMessage(exportId, format, item, prefix, position++); exportLogMessageDao.save(message); if (item.getItems() != null) { String subPrefix = prefix + "|" + format + item.getMessageKey(); for (ReportItem child : item.getItems()) { position = saveExportReportItem(exportId, format, child, subPrefix, position); } } return position; } private void saveExportReports(Long exportId, String format, List<Report> reports) { int position = 1; Filter filter = Filter.getNewEqualsFilter("parentId", exportId); List<ExportLogMessage> messages = exportLogMessageDao.select(filter); if (messages != null) { for (ExportLogMessage message : messages) { if (message.getPosition() >= position) position = message.getPosition() + 1; } } for (Report report : reports) { if (report instanceof GuiReport) position = saveExportReport(exportId, "", report, position); else position = saveExportReport(exportId, format + "_", report, position); } } private void saveFileValidationReport(Long validationId, Report report) { int position = 1; Filter filter = Filter.getNewEqualsFilter("parentId", validationId); List<FileValidationLogMessage> messages = fileValidationLogMessageDao.select(filter); if (messages != null) { for (FileValidationLogMessage message : messages) { if (message.getPosition() >= position) position = message.getPosition() + 1; } } FileValidationLogMessage message = new FileValidationLogMessage(validationId, "", report, position++); fileValidationLogMessageDao.save(message); if (report.getItems() != null) { // String prefix = report.getOriginKey(); // if (prefix == null || prefix.isEmpty()) // { // prefix = ((ReportItem) report).getMessageKey(); // } for (ReportItem item : report.getItems()) { position = saveFileValidationReportItem(validationId, item, "", position); } } } private int saveFileValidationReportItem(Long validationId, ReportItem item, String prefix, int position) { FileValidationLogMessage message = new FileValidationLogMessage(validationId, "", item, "", position++); fileValidationLogMessageDao.save(message); if (item.getItems() != null) { // String subPrefix = prefix+"|"+item.getMessageKey(); for (ReportItem child : item.getItems()) { position = saveFileValidationReportItem(validationId, child, "", position); } } return position; } private int saveImportReport(Long importId, String format, Report report, int position) { String prefix = report.getOriginKey(); if (prefix == null && report instanceof ReportItem) prefix = ((ReportItem) report).getMessageKey(); prefix = format + prefix; ImportLogMessage message = new ImportLogMessage(importId, format, report, position++); importLogMessageDao.save(message); if (report.getItems() != null) { for (ReportItem item : report.getItems()) { position = saveImportReportItem(importId, format, item, prefix, position); } } return position; } private int saveImportReportItem(Long importId, String format, ReportItem item, String prefix, int position) { ImportLogMessage message = new ImportLogMessage(importId, format, item, prefix, position++); importLogMessageDao.save(message); if (item.getItems() != null) { String subPrefix = prefix + "|" + format + item.getMessageKey(); for (ReportItem child : item.getItems()) { position = saveImportReportItem(importId, format, child, subPrefix, position); } } return position; } private int saveImportReports(Long importId, String format, List<Report> reports) { int position = 1; Filter filter = Filter.getNewEqualsFilter("parentId", importId); List<ImportLogMessage> messages = importLogMessageDao.select(filter); if (messages != null) { for (ImportLogMessage message : messages) { if (message.getPosition() >= position) position = message.getPosition() + 1; } } return saveImportReports(importId, format, position, reports); } private int saveImportReports(Long importId, String format, int position, List<Report> reports) { for (Report report : reports) { if (report instanceof GuiReport || report instanceof ExchangeReport) position = saveImportReport(importId, "", report, position); else position = saveImportReport(importId, format + "_", report, position); } return position; } /** * convert date string to calendar * @param simpleval * @return */ protected Calendar toCalendar(String simpleval) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); try { Date d = sdf.parse(simpleval); Calendar c = Calendar.getInstance(); c.setTime(d); return c; } catch (ParseException e) { logger.error("invalid date format : " + simpleval + " yyyy-MM-dd expected"); throw new RuntimeException("invalid date format : " + simpleval + " yyyy-MM-dd expected"); } } /** * @param commandNumber * @param name * @param parameters */ public void traceCommand(int commandNumber, String name, Map<String, List<String>> parameters) { System.out.println("Command " + commandNumber + " : " + name); for (String key : parameters.keySet()) { System.out.println(" parameters " + key + " : " + Arrays.toString(parameters.get(key).toArray())); } } /** * @param object * @param attrname * @param value * @throws Exception */ private void setAttribute(Object object, String attrname, String value) throws Exception { String name = attrname.toLowerCase(); if (name.equals("id")) { throw new Exception("non writable attribute id for any object , process stopped "); } if (!name.equals("objectid") && !name.equals("creatorid") && !name.equals("areacentroid") && name.endsWith("id")) { throw new Exception( "non writable attribute " + attrname + " use setReference instand , process stopped "); } Class<?> beanClass = object.getClass(); Method setter = findSetter(beanClass, attrname); Class<?> type = setter.getParameterTypes()[0]; if (type.isArray() || type.getSimpleName().equals("List")) { throw new Exception("list attribute " + attrname + " for object " + beanClass.getName() + " must be update with (add/remove)Attribute, process stopped "); } Object arg = null; if (type.isEnum()) { arg = toEnum(type, value); } else if (type.isPrimitive()) { arg = toPrimitive(type, value); } else { arg = toObject(type, value); } setter.invoke(object, arg); } /** * @param beanClass * @param attribute * @return * @throws Exception */ private Method findSetter(Class<?> beanClass, String attribute) throws Exception { return findAccessor(beanClass, attribute, "set", true); } /** * @param beanClass * @param attribute * @return * @throws Exception */ private Method findAccessor(Class<?> beanClass, String attribute, String prefix, boolean ex) throws Exception { String methodName = prefix + attribute; Method[] methods = beanClass.getMethods(); Method accessor = null; for (Method method : methods) { if (method.getName().equalsIgnoreCase(methodName)) { accessor = method; break; } } if (ex && accessor == null) { throw new Exception("unknown accessor " + prefix + " for attribute " + attribute + " for object " + beanClass.getName() + ", process stopped "); } return accessor; } protected Object toObject(Class<?> type, String value) throws Exception { if (value == null) return null; String name = type.getSimpleName(); if (name.equals("String")) return value; if (name.equals("Long")) return Long.valueOf(value); if (name.equals("Boolean")) return Boolean.valueOf(value); if (name.equals("Integer")) return Integer.valueOf(value); if (name.equals("Float")) return Float.valueOf(value); if (name.equals("Double")) return Double.valueOf(value); if (name.equals("BigDecimal")) return BigDecimal.valueOf(Double.parseDouble(value)); if (name.equals("Date")) { DateFormat dateFormat = null; if (value.contains("-") && value.contains(":")) { dateFormat = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss"); } else if (value.contains("-")) { dateFormat = new SimpleDateFormat("yyyy-MM-dd"); } else if (value.contains(":")) { dateFormat = new SimpleDateFormat("HH:mm:ss"); } else { throw new Exception("unable to convert " + value + " to Date"); } Date date = dateFormat.parse(value); return date; } if (name.equals("Time")) { DateFormat dateFormat = null; if (value.contains(":")) { dateFormat = new SimpleDateFormat("H:m:s"); } else { throw new Exception("unable to convert " + value + " to Time"); } Date date = dateFormat.parse(value); Time time = new Time(date.getTime()); return time; } throw new Exception("unable to convert String to " + type.getCanonicalName()); } protected Object toPrimitive(Class<?> type, String value) throws Exception { if (value == null) throw new Exception("primitive type " + type.getName() + " cannot be set to null"); String name = type.getName(); if (name.equals("long")) return Long.valueOf(value); if (name.equals("boolean")) return Boolean.valueOf(value); if (name.equals("int")) return Integer.valueOf(value); if (name.equals("float")) return Float.valueOf(value); if (name.equals("double")) return Double.valueOf(value); throw new Exception("unable to convert String to " + type.getName()); } protected Object toEnum(Class<?> type, String value) throws Exception { Method m = type.getMethod("fromValue", String.class); return m.invoke(null, value); } }