Author: chatellier Date: 2011-01-14 14:05:29 +0000 (Fri, 14 Jan 2011) New Revision: 505 Log: Interface d'admin de selection de resultat. Modification cot?\195?\169 web pour la r?\195?\169ception des r?\195?\169sultats. Nombreuse corrections apres retours. Added: trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/ExportUploadDialog.jaxx Modified: trunk/coser-business/src/main/java/fr/ifremer/coser/CoserBusinessConfig.java trunk/coser-business/src/main/java/fr/ifremer/coser/bean/Project.java trunk/coser-business/src/main/java/fr/ifremer/coser/bean/RSufiResult.java trunk/coser-business/src/main/java/fr/ifremer/coser/services/ImportService.java trunk/coser-business/src/main/java/fr/ifremer/coser/services/ProjectService.java trunk/coser-business/src/main/java/fr/ifremer/coser/services/WebService.java trunk/coser-business/src/main/java/fr/ifremer/coser/util/ProgressStream.java trunk/coser-business/src/main/resources/i18n/coser-business_en_GB.properties trunk/coser-business/src/main/resources/i18n/coser-business_fr_FR.properties trunk/coser-business/src/test/java/fr/ifremer/coser/services/ProjectServiceTest.java trunk/coser-business/src/test/java/fr/ifremer/coser/services/WebServiceTest.java trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/CoserFrameHandler.java trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/common/CommonHandler.java trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/control/ControlHandler.java trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/project/ProjectHandler.java trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/OtherDataFileListModel.java trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/ResultHandler.java trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/ResultTableModel.java trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/RsufiResultRenderer.java trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/RsufiResultTreeModel.java trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/SelectUploadResultView.jaxx trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/SelectionAddResultDialog.jaxx trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/ZoneComboBoxModel.java trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/ZoneComboBoxRenderer.java trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/selection/SelectionDetailsView.jaxx trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/selection/SelectionHandler.java trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/util/ErrorHelper.java trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/widgets/ComponentTitledBorder.java trunk/coser-ui/src/main/resources/fr/ifremer/coser/bean/RSufiResult-error-validation.xml trunk/coser-ui/src/main/resources/i18n/coser-ui_en_GB.properties trunk/coser-ui/src/main/resources/i18n/coser-ui_fr_FR.properties trunk/coser-web/src/main/java/fr/ifremer/coser/web/CoserWebConfig.java trunk/coser-web/src/main/java/fr/ifremer/coser/web/actions/UploadResultAction.java trunk/coser-web/src/main/resources/i18n/coser-web_en_GB.properties trunk/coser-web/src/main/resources/i18n/coser-web_fr_FR.properties Modified: trunk/coser-business/src/main/java/fr/ifremer/coser/CoserBusinessConfig.java =================================================================== --- trunk/coser-business/src/main/java/fr/ifremer/coser/CoserBusinessConfig.java 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-business/src/main/java/fr/ifremer/coser/CoserBusinessConfig.java 2011-01-14 14:05:29 UTC (rev 505) @@ -5,7 +5,7 @@ * $Id$ * $HeadURL$ * %% - * Copyright (C) 2010 Ifremer, Codelutin, Chatellier Eric + * Copyright (C) 2010 - 2011 Ifremer, Codelutin, Chatellier Eric * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as Modified: trunk/coser-business/src/main/java/fr/ifremer/coser/bean/Project.java =================================================================== --- trunk/coser-business/src/main/java/fr/ifremer/coser/bean/Project.java 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-business/src/main/java/fr/ifremer/coser/bean/Project.java 2011-01-14 14:05:29 UTC (rev 505) @@ -103,8 +103,7 @@ protected Control control; - // FIXME echatellier 20101217 compabilité avec les projets beta (a retirer pour la v1) - protected Date creationDate = new Date(0); + protected Date creationDate; protected Map<String, Selection> selections; Modified: trunk/coser-business/src/main/java/fr/ifremer/coser/bean/RSufiResult.java =================================================================== --- trunk/coser-business/src/main/java/fr/ifremer/coser/bean/RSufiResult.java 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-business/src/main/java/fr/ifremer/coser/bean/RSufiResult.java 2011-01-14 14:05:29 UTC (rev 505) @@ -42,8 +42,7 @@ /** serialVersionUID. */ private static final long serialVersionUID = -1337710082675120199L; - // FIXME echatellier 20110111 compabilité avec les projets beta (a retirer pour la v1) - protected Date creationDate = new Date(0); + protected Date creationDate; protected String name; Modified: trunk/coser-business/src/main/java/fr/ifremer/coser/services/ImportService.java =================================================================== --- trunk/coser-business/src/main/java/fr/ifremer/coser/services/ImportService.java 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-business/src/main/java/fr/ifremer/coser/services/ImportService.java 2011-01-14 14:05:29 UTC (rev 505) @@ -217,8 +217,8 @@ throw new CoserBusinessException(_("Wrong header detected in file %s. Find : %s, expected %s or %s", file.getAbsolutePath(), StringUtils.join(line, ", "), - StringUtils.join(enHeaders, ", "), - StringUtils.join(frHeaders, ", "))); + StringUtils.join(frHeaders, ", "), + StringUtils.join(enHeaders, ", "))); } } else { @@ -262,12 +262,11 @@ /** * Store project category data in specified file as csv. * - * @param project project containing data * @param content content to save * @param file file to save to * @throws CoserBusinessException */ - public void storeData(Project project, DataStorage content, File file) throws CoserBusinessException { + public void storeData(DataStorage content, File file) throws CoserBusinessException { // save content CSVWriter csvWriter = null; @@ -288,6 +287,49 @@ } /** + * Store data without quoting every columns with "" (r specific demand). + * + * @param content content to save + * @param file file to save to + * + * @throws CoserBusinessException + */ + public void storeDataWhithoutQuote(DataStorage content, File file) throws CoserBusinessException { + // save content + Writer writer = null; + try { + writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), CoserConstants.CSV_FILE_ENCODING)); + + Iterator<String[]> itContent = content.iterator(); + while (itContent.hasNext()) { + String[] contentDatas = itContent.next(); + + // start at 1 to not output "line" column + for (int i = 1 ; i < contentDatas.length ; i++) { + + if (i != 1) { + writer.write(CoserConstants.CSV_SEPARATOR_CHAR); + } + + String contentData = contentDatas[i]; + if (contentData.indexOf(CoserConstants.CSV_SEPARATOR_CHAR) > -1) { + writer.write("\"" + contentData + "\""); + } + else { + writer.write(contentData); + } + } + writer.write("\n"); + } + } catch (IOException ex) { + throw new CoserBusinessException("Can't save data", ex); + } + finally { + IOUtils.closeQuietly(writer); + } + } + + /** * Lit le fichier demandé et sauve dans une map les lignes demandées. * * @param file file to read Modified: trunk/coser-business/src/main/java/fr/ifremer/coser/services/ProjectService.java =================================================================== --- trunk/coser-business/src/main/java/fr/ifremer/coser/services/ProjectService.java 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-business/src/main/java/fr/ifremer/coser/services/ProjectService.java 2011-01-14 14:05:29 UTC (rev 505) @@ -30,16 +30,17 @@ import java.beans.Introspector; import java.io.BufferedOutputStream; +import java.io.BufferedWriter; import java.io.File; -import java.io.FileFilter; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; +import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintStream; -import java.nio.charset.Charset; +import java.io.Writer; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -66,21 +67,10 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.math.util.MathUtils; -import org.apache.http.HttpResponse; -import org.apache.http.client.ClientProtocolException; -import org.apache.http.client.HttpClient; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.mime.HttpMultipartMode; -import org.apache.http.entity.mime.MultipartEntity; -import org.apache.http.entity.mime.content.InputStreamBody; -import org.apache.http.entity.mime.content.StringBody; -import org.apache.http.impl.client.DefaultHttpClient; import org.nuiton.math.matrix.DimensionHelper; import org.nuiton.math.matrix.MatrixFactory; import org.nuiton.math.matrix.MatrixND; import org.nuiton.math.matrix.MatrixProvider; -import org.nuiton.util.FileUtil; -import org.nuiton.util.ZipUtil; import fr.ifremer.coser.CoserBusinessConfig; import fr.ifremer.coser.CoserBusinessException; @@ -103,7 +93,6 @@ import fr.ifremer.coser.data.Strata; import fr.ifremer.coser.storage.DataStorage; import fr.ifremer.coser.util.ProgressMonitor; -import fr.ifremer.coser.util.ProgressStream; /** * Service business method relative to project. @@ -797,7 +786,7 @@ log.debug("Saving control file : " + controlFile); } DataStorage content = getProjectContent(project, control, category, false); - importService.storeData(project, content, controlFile); + importService.storeData(content, controlFile); // save deleted content (if needed) DataStorage contentDeleted = getProjectContent(project, control, category, true); @@ -805,7 +794,7 @@ if (contentDeleted.size() > 1) { String deletedFileName = getDataStorageFileName(project, category, CoserConstants.STORAGE_DELECTED_SUFFIX); File deletedDataFile = new File(controlDirectory, deletedFileName); - importService.storeData(project, contentDeleted, deletedDataFile); + importService.storeData(contentDeleted, deletedDataFile); } } } @@ -991,7 +980,7 @@ } DataStorage content = getProjectContent(project, selection, category, false); - importService.storeData(project, content, dataFile); + importService.storeData(content, dataFile); // delete data are not saved here // can't delete data in selection @@ -1053,19 +1042,28 @@ else { rsufiResultDirectory.mkdirs(); + // ensure creation date (modifiable par l'ui) + if (rsufiResult.getCreationDate() == null) { + rsufiResult.setCreationDate(new Date()); + } + OutputStream outputStream = null; try { // sauvegarde des 2 fichiers obligatoires File estComIndFile = new File(rsufiResult.getEstComIndPath()); File estPopIndFile = new File(rsufiResult.getEstPopIndPath()); - File mapsDirectory = new File(rsufiResult.getMapsPath()); rsufiResult.setEstComIndName(estComIndFile.getName()); rsufiResult.setEstPopIndName(estPopIndFile.getName()); FileUtils.copyFileToDirectory(estComIndFile, rsufiResultDirectory); FileUtils.copyFileToDirectory(estPopIndFile, rsufiResultDirectory); File resultMapsDirectory = new File(rsufiResultDirectory, CoserConstants.STORAGE_MAPS_DIRECTORY); - FileUtils.copyDirectory(mapsDirectory, resultMapsDirectory); + // maps path is optionnal + if (StringUtils.isNotEmpty(rsufiResult.getMapsPath())) { + File mapsDirectory = new File(rsufiResult.getMapsPath()); + FileUtils.copyDirectory(mapsDirectory, resultMapsDirectory); + } + // sauvegarde des fichiers autre File otherFilesDirectory = new File(rsufiResultDirectory, "others"); for (File othersFile : othersFiles) { @@ -2304,194 +2302,6 @@ return matrix; } - - /** - * Présentation du graphique : histogramme de distribution en tailles par - * espèce, par strate et par année (une planche par espèce et par année) - * pour toute la série. Avec la possibilité de voir regroupé l'ensemble des - * années. - * - * Données. TAILLES$Nombres et TAILLES$Longueur - * Calcul. Sommer TAILLES$Nombres par classe de longueur (TAILLES$Longueur) - * sur tous les traits d'une année (ou tous les années si regroupé) - * - * - * @param project project - * @param dataContainer data container - * @return matrix 4 dimension - * - * @deprecated replaced by matrix proxy - */ - public MatrixND getLengthStructureNonProxy(Project project, AbstractDataContainer dataContainer) { - - // load map traitname > stratename - Map<String, String> haulAndStratas = new HashMap<String, String>(); - Iterator<String[]> itHaul = dataContainer.getHaul().iterator(true); - while (itHaul.hasNext()) { - String[] tuple = itHaul.next(); - String haul = tuple[Haul.INDEX_HAUL]; - String strataName = tuple[Haul.INDEX_STRATUM]; - haulAndStratas.put(haul, strataName); - } - - // map lengthstep, species , strata , year > count - Map<Double, Map<String, Map<String, Map<String, Double>>>> countForLengthSpeciesStrataYear = - new HashMap<Double, Map<String, Map<String, Map<String, Double>>>>(); - Set<Double> lengthSet = new HashSet<Double>(); - Set<String> speciesSet = new HashSet<String>(); - Set<String> strataSet = new HashSet<String>(); - Set<String> yearsSet = new HashSet<String>(); - - Iterator<String[]> itData = dataContainer.getLength().iterator(true); - while (itData.hasNext()) { - String[] tuple = itData.next(); - - String year = tuple[Length.INDEX_YEAR]; - String haul = tuple[Length.INDEX_HAUL]; - String species = tuple[Length.INDEX_SPECIES]; - String lengthAsString = tuple[Length.INDEX_LENGTH]; - String numberAsString = tuple[Length.INDEX_NUMBER]; - String strata = haulAndStratas.get(haul); - - if (strata == null) { - if (log.isWarnEnabled()) { - log.warn("No strata for haul " + haul); - } - continue; - } - - // remember for matrix spemantics - speciesSet.add(species); - strataSet.add(strata); - yearsSet.add(year); - - // get correct length step - // plain or half centimeters - try { - double length = Double.parseDouble(lengthAsString); - - // get length step to use - double ceil = Math.ceil(length); - double floor = Math.floor(length); - // ne pas prendre 0.5 car 10.0 serait arrondit à 10.5 - double round = Math.floor(length + 0.499999); - - // on prend le pas ou demi pas le plus proche - if (ceil == round) { - length = floor + 0.5; - } - else { - length = floor; - } - - lengthSet.add(length); - - try { - double number = Double.parseDouble(numberAsString); - - // fill map - Map<String, Map<String, Map<String, Double>>> lengthCountForSpeciesStrataYear = countForLengthSpeciesStrataYear.get(length); - if (lengthCountForSpeciesStrataYear == null) { - lengthCountForSpeciesStrataYear = new HashMap<String, Map<String,Map<String,Double>>>(); - countForLengthSpeciesStrataYear.put(length, lengthCountForSpeciesStrataYear); - } - - Map<String, Map<String, Double>> speciesCountForStrataYear = lengthCountForSpeciesStrataYear.get(species); - if (speciesCountForStrataYear == null) { - speciesCountForStrataYear = new HashMap<String, Map<String,Double>>(); - lengthCountForSpeciesStrataYear.put(species, speciesCountForStrataYear); - } - - Map<String, Double> strataCountForYear = speciesCountForStrataYear.get(strata); - if (strataCountForYear == null) { - strataCountForYear = new HashMap<String, Double>(); - speciesCountForStrataYear.put(strata, strataCountForYear); - } - - Double countForYear = strataCountForYear.get(year); - if (countForYear == null) { - strataCountForYear.put(year, number); - } - else { - double newCount = countForYear + number; - strataCountForYear.put(year, newCount); - } - } - catch (NumberFormatException ex) { - if (log.isWarnEnabled()) { - log.warn("Can't parse number as double : " + numberAsString); - } - } - } - catch (NumberFormatException ex) { - if (log.isWarnEnabled()) { - log.warn("Can't parse length as double : " + lengthAsString); - } - } - } - - // convert map to matrixND - List<Double> lengthSem = new ArrayList<Double>(lengthSet); - Collections.sort(lengthSem); - List<String> speciesSem = new ArrayList<String>(speciesSet); - Collections.sort(speciesSem); - List<String> strataSem = new ArrayList<String>(strataSet); - Collections.sort(strataSem); - List<String> yearsSem = new ArrayList<String>(yearsSet); - Collections.sort(yearsSem); - - if (log.isDebugEnabled()) { - log.debug(_("Creating matrix : %d*%d*%d*%d", lengthSem.size(), speciesSem.size(), strataSem.size(), yearsSem.size())); - } - - MatrixND matrix = MatrixFactory.getInstance().create(n_("coser.business.matrix.lengthstructure"), new List<?>[] { - lengthSem , speciesSem, strataSem, yearsSem}); - matrix.setDimensionName(0, n_("coser.business.common.length")); - matrix.setDimensionName(1, n_("coser.business.common.species")); - matrix.setDimensionName(2, n_("coser.business.common.strata")); - matrix.setDimensionName(3, n_("coser.business.common.years")); - - for (Map.Entry<Double, Map<String, Map<String, Map<String, Double>>>> lengthTuple : countForLengthSpeciesStrataYear.entrySet()) { - Double length = lengthTuple.getKey(); - for (Map.Entry<String, Map<String, Map<String, Double>>> speciesTuple : lengthTuple.getValue().entrySet()) { - String species = speciesTuple.getKey(); - for (Map.Entry<String, Map<String, Double>> strataTuple : speciesTuple.getValue().entrySet()) { - String strata = strataTuple.getKey(); - for (Map.Entry<String, Double> yearTuple : strataTuple.getValue().entrySet()) { - String year = yearTuple.getKey(); - matrix.setValue(new Object[]{length, species, strata, year}, yearTuple.getValue()); - } - } - } - } - - /*for (double length = minLength ; length <= maxLength ; length += (halfStep) ? 0.5 : 1) { - for (String species : speciesSem) { - for (String strata : strataSem) { - for (String year : yearsSem) { - - double value = 0.0; - Map<String, Map<String, Map<String, Double>>> lengthTuple = countForLengthSpeciesStrataYear.get(length); - if (lengthTuple != null) { - Map<String, Map<String, Double>> speciesTuple = lengthTuple.get(species); - if (speciesTuple != null) { - Map<String, Double> strataTuple = speciesTuple.get(strata); - if (strataTuple != null) { - Double number = strataTuple.get(year); - if (number != null) { - value = number; - } - } - } - } - matrix.setValue(new Object[]{length, species, strata, year}, value); - } - } - } - }*/ - - return matrix; - } /** * Présentation du graphique : histogramme de distribution en tailles par @@ -2679,21 +2489,8 @@ // plain or half centimeters try { double length = Double.parseDouble(lengthAsString); - - // get length step to use - double ceil = Math.ceil(length); - double floor = Math.floor(length); - // ne pas prendre 0.5 car 10.0 serait arrondit à 10.5 - double round = Math.floor(length + 0.499999); + length = getHalfStepValue(length); - // on prend le pas ou demi pas le plus proche - if (ceil == round) { - length = floor + 0.5; - } - else { - length = floor; - } - if (!matrix.getSemantic(0).contains(length)) { continue; } @@ -2721,8 +2518,34 @@ } /** - * Extrait les données de la selection + * Retourne la valeur au demi pas la plus proche. * + * 38.0 > 38.0 + * 38.1 > 38.0 + * 38.6 > 38.5 + * + * @param value value to get hasl step + * @return half step value + */ + protected double getHalfStepValue(double value) { + // get length step to use + double floor = Math.floor(value); + // ne pas prendre 0.5 car 10.0 serait arrondit à 10.5 + double round = Math.floor(value + 0.5); + + // on prend le pas ou demi pas le plus proche + if (floor == round) { + value = floor; + } + else { + value = floor + 0.5; + } + return value; + } + + /** + * Extrait les données de la selection pour rSufi. + * * @param project project * @param selection selection * @param directory directory to extract file to @@ -2744,13 +2567,29 @@ } DataStorage content = getProjectContent(project, selection, category, false); - importService.storeData(project, content, dataFile); + importService.storeDataWhithoutQuote(content, dataFile); } } // extract additionnal data file (selected species) File listSpeciesFile = new File(projectDirectory, "ListEspeces" + project.getName() + ".txt"); fillListSpeciesFile(selection, listSpeciesFile); + + // extract additionnal project information + File informationFile = new File(projectDirectory, "project.txt"); + PrintStream out = null; + try { + out = new PrintStream(new BufferedOutputStream(new FileOutputStream(informationFile))); + + out.println(_("coser.business.extract.projectName") + project.getName()); + out.println(_("coser.business.extract.projectAuthor") + project.getAuthor()); + out.println(_("coser.business.extract.projectComment") + project.getComment()); + } catch (IOException ex) { + throw new CoserBusinessException("Can't save project information file", ex); + } + finally { + IOUtils.closeQuietly(out); + } } /** @@ -2847,225 +2686,4 @@ return result; } - - /** - * Retourne tous les projets qui ont des résultats. - * - * De la forme d'une liste de de path (à la tree path) : - * ProjetName/SelectionName/ResultName - * - * @return results path - */ - public List<String[]> findAllProjectWithResult() { - List<String[]> results = new ArrayList<String[]>(); - - // loop on projets - File projectsDirectory = config.getProjectsDirectory(); - File[] projects = projectsDirectory.listFiles(); - if (projects != null) { - for (File existingProject : projects) { - if (existingProject.isDirectory()) { - String projectName = existingProject.getName(); - Project p = new Project(); - p.setName(projectName); - - // loop on selections - File selectionsDirectory = new File(existingProject, CoserConstants.STORAGE_SELECTION_DIRECTORY); - File[] selections = selectionsDirectory.listFiles(); - if (selections != null) { - for (File existingSelection : selections) { - if (existingSelection.isDirectory()) { - String selectionName = existingSelection.getName(); - Selection s = new Selection(); - s.setName(selectionName); - - // loop on result - File rsufisDirectory = new File(existingSelection, CoserConstants.STORAGE_RESULTS_DIRECTORY); - File[] rSufiResults = rsufisDirectory.listFiles(); - if (rSufiResults != null) { - for (File rSufiResult : rSufiResults) { - if (rSufiResult.isDirectory()) { - String resultName = rSufiResult.getName(); - RSufiResult r = new RSufiResult(); - r.setName(resultName); - - String[] result = new String[] {projectName, selectionName, resultName}; - results.add(result); - } - } - } - } - } - } - } - } - } - - return results; - } - - /** - * Upload user selected result to coser web front-end using common http - * client. - * - * @param selectedResults selected result (collection of project/selection/rsufiresultname) - * @param progress progress monitor - * @throws CoserBusinessException - */ - public void performResultUpload(Collection<String[]> selectedResults, ProgressMonitor progress) throws CoserBusinessException { - - // first copy prepare directory with only necessary data - // ie project with only selected selections - // and selection with only selected results - - progress.setText(_("coser.business.uploadresult.preparezip")); - progress.setCurrent(0); - - File prepareZip = null; - try { - prepareZip = File.createTempFile("coserprepare-", ".zip"); - prepareZip.deleteOnExit(); - - // copy selectively all data to target directory - MultipleFileFilter mFileFilters = new MultipleFileFilter(); - for (String[] path : selectedResults) { - OneResultFileFilter oneRFF = new OneResultFileFilter(config, path[0], path[1], path[2]); - mFileFilters.add(oneRFF); - } - - // create zip temp file - File projectsDirectory = config.getProjectsDirectory(); - - //ZipUtil.compress(prepareZip, projectsDirectory, mFileFilters); - // compress les projets à la racines de l'archive - // sans le dossier "projects" - Collection<File> files = FileUtil.getFilteredElements(projectsDirectory, mFileFilters, true); - ZipUtil.compressFiles(prepareZip, projectsDirectory, files, false); - } catch (IOException ex) { - throw new CoserBusinessException("Can't prepare upload data", ex); - } - - progress.setText(_("coser.business.uploadresult.sendzip")); - progress.setTotal((int)prepareZip.length()); - - // then upload zip file to website - try { - HttpClient httpclient = new DefaultHttpClient(); - MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE); - - // password param - StringBody passwordBody = new StringBody("toto", Charset.forName("UTF-8")); - reqEntity.addPart("password", passwordBody); - - // file param - ProgressStream stream = new ProgressStream(new FileInputStream(prepareZip), progress); - InputStreamBody fileBody = new InputStreamBody(stream, "application/zip", prepareZip.getName()); - reqEntity.addPart("resultFile", fileBody); - - HttpPost httppost = new HttpPost(config.getWebUploadURL()); - httppost.setEntity(reqEntity); - - if (log.isInfoEnabled()) { - log.info("Uploading " + prepareZip + " to " + httppost.getURI()); - } - - HttpResponse response = httpclient.execute(httppost); - - if (log.isDebugEnabled()) { - log.debug("Upload response code : " + response.getStatusLine()); - } - } catch (ClientProtocolException ex) { - throw new CoserBusinessException("Can't upload file", ex); - } catch (IOException ex) { - throw new CoserBusinessException("Can't upload file", ex); - } - } - - /** - * Aggrege plusieurs file filters. - */ - protected static class MultipleFileFilter implements FileFilter { - protected Collection<FileFilter> fileFilters = new ArrayList<FileFilter>(); - - public void add(FileFilter f) { - fileFilters.add(f); - } - - /* - * @see java.io.FileFilter#accept(java.io.File) - */ - @Override - public boolean accept(File pathname) { - - boolean result = false; - Iterator<FileFilter> it = fileFilters.iterator(); - while (it.hasNext() && !result) { - result = it.next().accept(pathname); - } - return result; - } - } - - /** - * Filter pour un resultat donné. - * - * Attention, implémentation que ne doit fonctionner que avec ZipUtil - * car meme si on refuse en répertoire, il redemande quand même - * les fils (et il faut qu'il les demande) - */ - protected static class OneResultFileFilter implements FileFilter { - protected CoserBusinessConfig config; - protected String project; - protected String selection; - protected String rsufi; - - public OneResultFileFilter(CoserBusinessConfig config, String project, String selection, String rsufi) { - this.config = config; - this.project = project; - this.selection = selection; - this.rsufi = rsufi; - } - - /* - * @see java.io.FileFilter#accept(java.io.File) - */ - @Override - public boolean accept(File pathname) { - - boolean result = false; - - try { - String currentPathName = pathname.getCanonicalPath() + File.separator; - - File projectDirectory = new File(config.getProjectsDirectory(), project); - File selectionsDirectory = new File(projectDirectory, CoserConstants.STORAGE_SELECTION_DIRECTORY); - File selectionDirectory = new File(selectionsDirectory, selection); - File resultsDirectory = new File(selectionDirectory, CoserConstants.STORAGE_RESULTS_DIRECTORY); - File resultDirectory = new File(resultsDirectory, rsufi); - - String projectPath = projectDirectory.getCanonicalPath() + File.separator; - String selectionsPath = selectionsDirectory.getCanonicalPath() + File.separator; - String selectionPath = selectionDirectory.getCanonicalPath() + File.separator; - String resultsPath = resultsDirectory.getCanonicalPath() + File.separator; - String resultPath = resultDirectory.getCanonicalPath() + File.separator; - - // on prend - // - tout ce qu'il y a dans le projet - // - sauf le répertoire "selections" - // - ou la selection entierement - // - sauf le répertoire result - // - ou le resultat entierrement - result = (currentPathName.startsWith(projectPath) - && !currentPathName.startsWith(selectionsPath)) - || (currentPathName.startsWith(selectionPath) - && !currentPathName.startsWith(resultsPath)) - || currentPathName.startsWith(resultPath); - - } catch (IOException ex) { - throw new RuntimeException("Can't get system canonical path"); - } - - return result; - } - } } Modified: trunk/coser-business/src/main/java/fr/ifremer/coser/services/WebService.java =================================================================== --- trunk/coser-business/src/main/java/fr/ifremer/coser/services/WebService.java 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-business/src/main/java/fr/ifremer/coser/services/WebService.java 2011-01-14 14:05:29 UTC (rev 505) @@ -28,34 +28,52 @@ import static org.nuiton.i18n.I18n._; import java.io.File; +import java.io.FileFilter; +import java.io.FileInputStream; import java.io.IOException; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Collection; +import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.TreeMap; +import java.util.regex.Matcher; import org.apache.commons.collections.map.MultiKeyMap; import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.mail.EmailException; import org.apache.commons.mail.MultiPartEmail; +import org.apache.http.HttpResponse; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.mime.HttpMultipartMode; +import org.apache.http.entity.mime.MultipartEntity; +import org.apache.http.entity.mime.content.InputStreamBody; +import org.apache.http.entity.mime.content.StringBody; +import org.apache.http.impl.client.DefaultHttpClient; import org.nuiton.util.FileUtil; +import org.nuiton.util.StringUtil; import org.nuiton.util.ZipUtil; import fr.ifremer.coser.CoserBusinessConfig; import fr.ifremer.coser.CoserBusinessException; import fr.ifremer.coser.CoserConstants; import fr.ifremer.coser.CoserConstants.Category; +import fr.ifremer.coser.CoserUtils; import fr.ifremer.coser.bean.Project; import fr.ifremer.coser.bean.RSufiResult; +import fr.ifremer.coser.bean.Selection; import fr.ifremer.coser.storage.DataStorage; import fr.ifremer.coser.storage.MemoryDataStorage; +import fr.ifremer.coser.util.ProgressMonitor; +import fr.ifremer.coser.util.ProgressStream; /** * Service specifique à l'interface web de visualisation. @@ -153,6 +171,341 @@ } /** + * Retourne tous les projets qui ont des résultats. + * + * De la forme d'une liste de de path (à la tree path) : + * ProjetName/SelectionName/ResultName + * + * @param beginDate begin date (can be null) + * @param endDate end date (can be null) + * @param onlyPubliableResult select only publiable results + * + * @return results path + * @throws CoserBusinessException + */ + public List<Object[]> findAllProjectWithResult(Date beginDate, Date endDate, boolean onlyPubliableResult) throws CoserBusinessException { + List<Object[]> results = new ArrayList<Object[]>(); + + // loop on projets + File projectsDirectory = config.getProjectsDirectory(); + File[] projects = projectsDirectory.listFiles(); + if (projects != null) { + for (File existingProject : projects) { + if (existingProject.isDirectory()) { + String projectName = existingProject.getName(); + Project p = new Project(); + p.setName(projectName); + + // loop on selections + File selectionsDirectory = new File(existingProject, CoserConstants.STORAGE_SELECTION_DIRECTORY); + File[] selections = selectionsDirectory.listFiles(); + if (selections != null) { + for (File existingSelection : selections) { + if (existingSelection.isDirectory()) { + String selectionName = existingSelection.getName(); + Selection s = new Selection(); + s.setName(selectionName); + + // loop on result + File rsufisDirectory = new File(existingSelection, CoserConstants.STORAGE_RESULTS_DIRECTORY); + File[] rSufiResults = rsufisDirectory.listFiles(); + if (rSufiResults != null) { + for (File rSufiResult : rSufiResults) { + if (rSufiResult.isDirectory()) { + RSufiResult r = projectService.getRSufiResult(rSufiResult); + + boolean candidate = isCandidateResult(r, beginDate, endDate, onlyPubliableResult); + if (candidate) { + Object[] result = new Object[] {p, s, r}; + results.add(result); + } + } + } + } + } + } + } + } + } + } + + return results; + } + + /** + * Test if result is valid with filtering. + * + * @param rsufiResult rsufi result to test + * @param beginDate begin date (can be null) + * @param endDate end date (can be null) + * @param onlyPubliableResult select only publiable results + * @return if result is valid candidate + */ + protected boolean isCandidateResult(RSufiResult rsufiResult, Date beginDate, + Date endDate, boolean onlyPubliableResult) { + + boolean result = true; + + if (beginDate != null) { + result &= rsufiResult.getCreationDate().compareTo(beginDate) >= 0; + } + + if (endDate != null) { + result &= rsufiResult.getCreationDate().compareTo(endDate) <= 0; + } + + if (onlyPubliableResult) { + result &= rsufiResult.isPublishResult(); + } + + return result; + } + + /** + * Extract directory to custom directory. + * + * @param selectedResults selected result paths + * @param extractDirectory extract directory (can be null) + * @param exportWithData include csv data during export + * @return extracted file (no automatically deleted) + * @throws CoserBusinessException + */ + public File performResultExtract(Collection<Object[]> selectedResults, File extractDirectory, boolean exportWithData) throws CoserBusinessException { + File prepareZip = null; + try { + prepareZip = File.createTempFile("coserextract-", ".zip", extractDirectory); + + // copy selectively all data to target directory + MultipleFileFilter mFileFilters = new MultipleFileFilter(); + for (Object[] path : selectedResults) { + // load projet, needed to known source data file name + Project project = (Project)path[0]; + project = projectService.openProject(project.getName()); + + OneResultFileFilter oneRFF = new OneResultFileFilter(config, + (Project)path[0], (Selection)path[1], (RSufiResult)path[2], exportWithData); + mFileFilters.add(oneRFF); + } + + // create zip temp file + File projectsDirectory = config.getProjectsDirectory(); + + //ZipUtil.compress(prepareZip, projectsDirectory, mFileFilters); + // compress les projets à la racines de l'archive + // sans le dossier "projects" + Collection<File> files = FileUtil.getFilteredElements(projectsDirectory, mFileFilters, true); + ZipUtil.compressFiles(prepareZip, projectsDirectory, files, false); + } catch (IOException ex) { + throw new CoserBusinessException("Can't prepare upload data", ex); + } + + return prepareZip; + } + + /** + * Upload user selected result to coser web front-end using common http + * client. + * + * @param selectedResults selected result (collection of project/selection/rsufiresult) + * @param login remote admin login + * @param password remote admin password + * @param progress progress monitor + * @throws CoserBusinessException + */ + public void performResultUpload(Collection<Object[]> selectedResults, String login, String password, ProgressMonitor progress) throws CoserBusinessException { + + // first copy prepare directory with only necessary data + // ie project with only selected selections + // and selection with only selected results + + progress.setCurrent(0); + progress.setText(_("coser.business.uploadresult.checkcollision")); + checkDataCollision(selectedResults); + + progress.setText(_("coser.business.uploadresult.preparezip")); + + // default extract to temp directory with data sources + File prepareZip = performResultExtract(selectedResults, null, true); + + progress.setText(_("coser.business.uploadresult.sendzip")); + progress.setTotal((int)prepareZip.length()); + + // then upload zip file to website + try { + HttpClient httpclient = new DefaultHttpClient(); + MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE); + + // login/password param (password encoded) + StringBody loginBody = new StringBody(login, Charset.forName("UTF-8")); + reqEntity.addPart("login", loginBody); + String sha1password = StringUtil.encodeSHA1(password); + StringBody passwordBody = new StringBody(sha1password, Charset.forName("UTF-8")); + reqEntity.addPart("sha1Password", passwordBody); + + // file param + ProgressStream stream = new ProgressStream(new FileInputStream(prepareZip), progress); + InputStreamBody fileBody = new InputStreamBody(stream, "application/zip", prepareZip.getName()); + reqEntity.addPart("resultFile", fileBody); + + HttpPost httppost = new HttpPost(config.getWebUploadURL()); + httppost.setEntity(reqEntity); + + if (log.isInfoEnabled()) { + log.info("Uploading " + prepareZip + " to " + httppost.getURI()); + } + + HttpResponse response = httpclient.execute(httppost); + + if (log.isDebugEnabled()) { + log.debug("Upload response code : " + response.getStatusLine()); + } + } catch (ClientProtocolException ex) { + throw new CoserBusinessException("Can't upload file", ex); + } catch (IOException ex) { + throw new CoserBusinessException("Can't upload file", ex); + } + + prepareZip.delete(); + } + + /** + * Met à jour les fichiers de propriétés des resultats (maps, dataSource) + * and check for duplicated couple (zoneid/resulttype (map) upload). + * + * @param selectedResults result id to check + * @throws CoserBusinessException + */ + protected void checkDataCollision(Collection<Object[]> selectedResults) throws CoserBusinessException { + + Collection<String> resultZoneTypeIds = new ArrayList<String>(); + + for (Object[] selectedResult : selectedResults) { + Project project = (Project)selectedResult[0]; + Selection selection = (Selection)selectedResult[1]; + RSufiResult rsufiResult = (RSufiResult)selectedResult[2]; + + // on creer une clé composé pour l'id du resultat + String resultZoneTypeId = rsufiResult.getZone() + String.valueOf(rsufiResult.isMapsReferenceResult()); + if (resultZoneTypeIds.contains(resultZoneTypeId)) { + throw new CoserBusinessException(_("coser.business.resultupload.duplicatedresult", + project.getName(), selection.getName(), rsufiResult.getName(), rsufiResult.getZone())); + } else { + resultZoneTypeIds.add(resultZoneTypeId); + } + } + } + + /** + * Aggrege plusieurs file filters. + */ + protected static class MultipleFileFilter implements FileFilter { + protected Collection<FileFilter> fileFilters = new ArrayList<FileFilter>(); + + public void add(FileFilter f) { + fileFilters.add(f); + } + + /* + * @see java.io.FileFilter#accept(java.io.File) + */ + @Override + public boolean accept(File pathname) { + + boolean result = false; + Iterator<FileFilter> it = fileFilters.iterator(); + while (it.hasNext() && !result) { + result = it.next().accept(pathname); + } + return result; + } + } + + /** + * Filter pour un resultat donné. + * + * Attention, implémentation que ne doit fonctionner que avec ZipUtil + * car meme si on refuse en répertoire, il redemande quand même + * les fils (et il faut qu'il les demande) + */ + protected class OneResultFileFilter implements FileFilter { + protected CoserBusinessConfig config; + protected Project project; + protected Selection selection; + protected RSufiResult rsufi; + protected boolean exportWithData; + + public OneResultFileFilter(CoserBusinessConfig config, Project project, Selection selection, RSufiResult rsufi, boolean exportWithData) { + this.config = config; + this.project = project; + this.selection = selection; + this.rsufi = rsufi; + this.exportWithData = exportWithData; + } + + /* + * @see java.io.FileFilter#accept(java.io.File) + */ + @Override + public boolean accept(File pathname) { + + boolean result = false; + + try { + String currentPathName = pathname.getCanonicalPath() + File.separator; + + File projectDirectory = new File(config.getProjectsDirectory(), project.getName()); + File selectionsDirectory = new File(projectDirectory, CoserConstants.STORAGE_SELECTION_DIRECTORY); + File selectionDirectory = new File(selectionsDirectory, selection.getName()); + File resultsDirectory = new File(selectionDirectory, CoserConstants.STORAGE_RESULTS_DIRECTORY); + File resultDirectory = new File(resultsDirectory, rsufi.getName()); + + String projectPath = projectDirectory.getCanonicalPath() + File.separator; + String selectionsPath = selectionsDirectory.getCanonicalPath() + File.separator; + String selectionPath = selectionDirectory.getCanonicalPath() + File.separator; + String resultsPath = resultsDirectory.getCanonicalPath() + File.separator; + String resultPath = resultDirectory.getCanonicalPath() + File.separator; + + // on prend + // - tout ce qu'il y a dans le projet + // - sauf le répertoire "selections" + // - ou la selection entierement + // - sauf le répertoire result + // - ou le resultat entierrement + result = (currentPathName.startsWith(projectPath) + && !currentPathName.startsWith(selectionsPath)) + || (currentPathName.startsWith(selectionPath) + && !currentPathName.startsWith(resultsPath)) + || currentPathName.startsWith(resultPath); + + // cas ou les données sources ne doivent pas être exporter + // condition sur les nom de fichier ? + if (!exportWithData) { + String fileName = pathname.getName(); + + // on exclu tout les fichiers qui commence + // par les meme nom de fichier que ceux du projet + // (les noms de fichier sont personnalisable) + for (Category category : Category.values()) { + if (category.isDataCategory()) { + String sourceFileName = projectService.getDataStorageFileName(project, category, null); + Matcher matcher = CoserUtils.FILENAME_SUFFIX_PATTERN.matcher(sourceFileName); + if (matcher.matches()) { + result &= !(fileName.startsWith(matcher.group(1)) && fileName.endsWith(matcher.group(2))); + } else { + result &= !fileName.startsWith(sourceFileName); + } + } + } + } + } catch (IOException ex) { + throw new RuntimeException("Can't get system canonical path"); + } + + return result; + } + } + + /** * Traite le fichier uploade par l'application client et l'enregistre * dans le stockage coté web. * @@ -284,8 +637,7 @@ if (newResultIds.contains(resultResultId)) { // un nouveau resulat utilsera ce resultid FileUtils.deleteDirectory(resultFile); - } - else { + } else { // un resultat valid trouvé, selection non a supprimer selectionResultCount++; } @@ -296,8 +648,7 @@ // si aucun resultat valide, suppression de la seletion if (selectionResultCount == 0) { FileUtils.deleteDirectory(selectionFile); - } - else { + } else { projectSelectionCount++; } } Modified: trunk/coser-business/src/main/java/fr/ifremer/coser/util/ProgressStream.java =================================================================== --- trunk/coser-business/src/main/java/fr/ifremer/coser/util/ProgressStream.java 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-business/src/main/java/fr/ifremer/coser/util/ProgressStream.java 2011-01-14 14:05:29 UTC (rev 505) @@ -39,9 +39,9 @@ */ public class ProgressStream extends InputStream { - public InputStream delegateStream; + protected InputStream delegateStream; - public ProgressMonitor delegateProgress; + protected ProgressMonitor delegateProgress; public ProgressStream(InputStream delegateStream, ProgressMonitor delegateProgress) { super(); Modified: trunk/coser-business/src/main/resources/i18n/coser-business_en_GB.properties =================================================================== --- trunk/coser-business/src/main/resources/i18n/coser-business_en_GB.properties 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-business/src/main/resources/i18n/coser-business_en_GB.properties 2011-01-14 14:05:29 UTC (rev 505) @@ -66,6 +66,9 @@ coser.business.control.step.diffCatchLength=Check diff catch/length (%d%%) coser.business.control.step.observation=Checking observation number \: %s (%d%%) coser.business.control.step.xworks=Line checks \: %s (%d%%) +coser.business.extract.projectAuthor=Project author \: +coser.business.extract.projectComment=Project comment \: +coser.business.extract.projectName=Project name \: coser.business.line=Line coser.business.matrix.density=Density coser.business.matrix.lengthstructure=Length structures @@ -91,7 +94,9 @@ coser.business.publication.selectionlogexporttitle= coser.business.publication.stratafilename=Strata file name coser.business.result.rsufiResultAlreadyExists=Result %s already exists \! +coser.business.resultupload.duplicatedresult=Result %s/%s/%s duplicate another result for zone %s \! coser.business.selection.notValidatedControl=Not validated control \! +coser.business.uploadresult.checkcollision=Checking zone collisions coser.business.uploadresult.preparezip=Preparing zip archive\u2026 coser.business.uploadresult.sendzip=Sending zip archive\u2026 coser.config.control.diffcatchlength.description=Percentage difference allowed between catch and length (in percent, for example 5% set 5.0) Modified: trunk/coser-business/src/main/resources/i18n/coser-business_fr_FR.properties =================================================================== --- trunk/coser-business/src/main/resources/i18n/coser-business_fr_FR.properties 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-business/src/main/resources/i18n/coser-business_fr_FR.properties 2011-01-14 14:05:29 UTC (rev 505) @@ -66,6 +66,9 @@ coser.business.control.step.diffCatchLength=V\u00E9rification des diff\u00E9rences captures/taille (%d%%) coser.business.control.step.observation=V\u00E9rification du nombre d'observation \: %s (%d%%) coser.business.control.step.xworks=Validation par lignes \: %s (%d%%) +coser.business.extract.projectAuthor=Auteur du projet \: +coser.business.extract.projectComment=Commentaire du projet \: +coser.business.extract.projectName=Nom du project \: coser.business.line=Ligne coser.business.matrix.density=Densit\u00E9 coser.business.matrix.lengthstructure=Structures en taille @@ -91,7 +94,9 @@ coser.business.publication.selectionlogexporttitle=Rapport de la s\u00E9lection %s (projet %s) coser.business.publication.stratafilename=Nom du fichier strates coser.business.result.rsufiResultAlreadyExists=Le r\u00E9sultat %D existe d\u00E9j\u00E0 \! +coser.business.resultupload.duplicatedresult=Le r\u00E9sultat %s/%s/%s duplique un autre r\u00E9sultat pour la zone %s \! coser.business.selection.notValidatedControl=Contr\u00F4le non valid\u00E9 \! +coser.business.uploadresult.checkcollision=V\u00E9rification des collisions de zones coser.business.uploadresult.preparezip=Pr\u00E9paration de l'archive zip\u2026 coser.business.uploadresult.sendzip=Envoi de l'archive zip\u2026 coser.config.control.diffcatchlength.description=Pourcentage d'\u00E9cart tol\u00E9r\u00E9 entre les captures et les tailles (en pourcent, par exemple pour 5% mettre 5.0) Modified: trunk/coser-business/src/test/java/fr/ifremer/coser/services/ProjectServiceTest.java =================================================================== --- trunk/coser-business/src/test/java/fr/ifremer/coser/services/ProjectServiceTest.java 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-business/src/test/java/fr/ifremer/coser/services/ProjectServiceTest.java 2011-01-14 14:05:29 UTC (rev 505) @@ -460,4 +460,18 @@ MatrixND matrix = projectService.getLengthStructure(project, selection); Assert.assertNotNull(matrix); } + + /** + * Test le calcul du demi pas pour une valeur. + */ + @Test + public void testHalfStepValue() { + Assert.assertEquals(38.0, projectService.getHalfStepValue(38.0), 0.00001); + Assert.assertEquals(38.0, projectService.getHalfStepValue(38.1), 0.00001); + Assert.assertEquals(38.0, projectService.getHalfStepValue(38.245), 0.00001); + Assert.assertEquals(38.5, projectService.getHalfStepValue(38.5), 0.00001); + Assert.assertEquals(38.5, projectService.getHalfStepValue(38.6), 0.00001); + Assert.assertEquals(38.5, projectService.getHalfStepValue(38.999), 0.00001); + Assert.assertEquals(42.5, projectService.getHalfStepValue(42.745), 0.00001); + } } Modified: trunk/coser-business/src/test/java/fr/ifremer/coser/services/WebServiceTest.java =================================================================== --- trunk/coser-business/src/test/java/fr/ifremer/coser/services/WebServiceTest.java 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-business/src/test/java/fr/ifremer/coser/services/WebServiceTest.java 2011-01-14 14:05:29 UTC (rev 505) @@ -38,7 +38,6 @@ import org.nuiton.util.ZipUtil; import fr.ifremer.coser.CoserBusinessException; -import fr.ifremer.coser.bean.Project; import fr.ifremer.coser.storage.DataStorage; /** @@ -88,7 +87,7 @@ @Test public void testGetZones() throws CoserBusinessException { DataStorage zones = webService.getZonesMap(); - Assert.assertEquals(16, zones.size()); + Assert.assertEquals(17, zones.size()); } /** Modified: trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/CoserFrameHandler.java =================================================================== --- trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/CoserFrameHandler.java 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/CoserFrameHandler.java 2011-01-14 14:05:29 UTC (rev 505) @@ -502,14 +502,10 @@ * Display ui to select result to upload to website or to export as archive. */ public void showPublishResultView() { - ProjectService projectService = view.getContextValue(ProjectService.class); - List<String[]> results = projectService.findAllProjectWithResult(); - SelectUploadResultView selectUploadResultView = new SelectUploadResultView(view); - selectUploadResultView.setHandler(new ResultHandler()); - SwingUtil.fixTableColumnWidth(selectUploadResultView.getSelectedProjectTable(), 1, 25); - selectUploadResultView.getSelectedProjectTable().setDefaultRenderer(String[].class, new RsufiResultRenderer()); - selectUploadResultView.getSelectedProjectTableModel().setResultPath(results); + ResultHandler handler = new ResultHandler(); + selectUploadResultView.setHandler(handler); + handler.init(selectUploadResultView); setMainComponent(selectUploadResultView); } } Modified: trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/common/CommonHandler.java =================================================================== --- trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/common/CommonHandler.java 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/common/CommonHandler.java 2011-01-14 14:05:29 UTC (rev 505) @@ -31,6 +31,7 @@ import java.io.File; import java.io.IOException; +import javax.swing.JFileChooser; import javax.swing.JOptionPane; /** @@ -44,7 +45,23 @@ */ public class CommonHandler { + /** File chooser instance. */ + protected JFileChooser fileChooserInstance; + /** + * Retourne une unique instance du file chooser pour conserver + * le répertoire de sélection d'un appel sur l'autre. + * + * @return file chooser + */ + protected JFileChooser getFileChooserInstance() { + if (fileChooserInstance == null) { + fileChooserInstance = new JFileChooser(); + } + return fileChooserInstance; + } + + /** * Install le curseur sablier. * * @param comp component to set cursor Modified: trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/control/ControlHandler.java =================================================================== --- trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/control/ControlHandler.java 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/control/ControlHandler.java 2011-01-14 14:05:29 UTC (rev 505) @@ -376,7 +376,7 @@ SwingWorker<List<ControlError>, Void> task = new SwingWorker<List<ControlError>, Void>() { - long before = System.currentTimeMillis(); + protected long before = System.currentTimeMillis(); @Override protected List<ControlError> doInBackground() { Modified: trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/project/ProjectHandler.java =================================================================== --- trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/project/ProjectHandler.java 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/project/ProjectHandler.java 2011-01-14 14:05:29 UTC (rev 505) @@ -63,22 +63,7 @@ private static final Log log = LogFactory.getLog(ProjectHandler.class); - protected JFileChooser fileChooser; - protected JFileChooser mapFileChooser; - - /** - * Retourne une unique instance du file chooser pour conserver - * le répertoire de sélection d'un appel sur l'autre. - * - * @return l'unique instance de file chooser - */ - protected JFileChooser getFileChooser() { - if (fileChooser == null) { - fileChooser = new JFileChooser(); - } - return fileChooser; - } /** * Retourne une unique instance du file chooser pour conserver @@ -112,8 +97,9 @@ * @param textComponent text component to fill */ public void selectInputFile(ProjectCreationView projectView, JTextField textComponent) { - JFileChooser selectFileChooser = getFileChooser(); - + JFileChooser selectFileChooser = getFileChooserInstance(); + selectFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); + int result = selectFileChooser.showOpenDialog(projectView); if (result == JFileChooser.APPROVE_OPTION) { File selectedFile = selectFileChooser.getSelectedFile(); @@ -242,7 +228,7 @@ setWaitCursor(projectView); SwingWorker<Project, Void> task = new SwingWorker<Project, Void>() { - long before = System.currentTimeMillis(); + protected long before = System.currentTimeMillis(); @Override protected Project doInBackground() { Added: trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/ExportUploadDialog.jaxx =================================================================== --- trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/ExportUploadDialog.jaxx (rev 0) +++ trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/ExportUploadDialog.jaxx 2011-01-14 14:05:29 UTC (rev 505) @@ -0,0 +1,95 @@ +<!-- + #%L + Coser :: UI + + $Id$ + $HeadURL$ + %% + Copyright (C) 2010 - 2011 Ifremer, Codelutin, Chatellier Eric + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 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 General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program. If not, see + <http://www.gnu.org/licenses/gpl-3.0.html>. + #L% + --> +<JDialog title="coser.ui.uploadresult.exportUploadTitle" modal="true"> + <Table> + <ResultHandler id="handler" javaBean="null" /> + + <row> + <cell weightx="1" weighty="1" fill="both"> + <Table border='{BorderFactory.createTitledBorder(_("coser.ui.uploadresult.extractChoice"))}'> + <row> + <cell fill="horizontal"> + <JLabel text="coser.ui.uploadresult.extractTo" /> + </cell> + <cell weightx="1" fill="horizontal"> + <JTextField id="extractToTextField" /> + </cell> + <cell> + <JButton text="coser.ui.common.selectFile" + onActionPerformed="getHandler().selectExportDirectory(this, extractToTextField)" /> + </cell> + </row> + <row> + <cell anchor="east"> + <JCheckBox id="sourceDataExport" selected="true" /> + </cell> + <cell columns="2"> + <JLabel text="coser.ui.uploadresult.extractWithData" /> + </cell> + </row> + <row> + <cell columns="3" anchor="east"> + <JButton text="coser.ui.uploadresult.extract" + onActionPerformed="getHandler().performExtractResult(this)" /> + </cell> + </row> + </Table> + </cell> + </row> + <row> + <cell weightx="1" weighty="1" fill="both"> + <Table border='{BorderFactory.createTitledBorder(_("coser.ui.uploadresult.uploadChoice"))}'> + <row> + <cell fill="horizontal"> + <JLabel text="coser.ui.uploadresult.uploadLogin" /> + </cell> + <cell weightx="1" fill="horizontal"> + <JTextField id="uploadLogintextField" /> + </cell> + </row> + <row> + <cell> + <JLabel text="coser.ui.uploadresult.uploadPassword" /> + </cell> + <cell> + <JPasswordField id="uploadPasswordtextField" /> + </cell> + </row> + <row> + <cell columns="2" anchor="east"> + <JButton text="coser.ui.uploadresult.upload" + onActionPerformed="getHandler().performUploadResult(this)" /> + </cell> + </row> + <row> + <cell weightx="1" fill="horizontal" columns="2"> + <fr.ifremer.coser.ui.util.CoserProgressBar id="uploadProgressBar" stringPainted="true" /> + </cell> + </row> + </Table> + </cell> + </row> + </Table> +</JDialog> \ No newline at end of file Modified: trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/OtherDataFileListModel.java =================================================================== --- trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/OtherDataFileListModel.java 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/OtherDataFileListModel.java 2011-01-14 14:05:29 UTC (rev 505) @@ -5,7 +5,7 @@ * $Id$ * $HeadURL$ * %% - * Copyright (C) 2010 Ifremer, Codelutin, Chatellier Eric + * Copyright (C) 2010 - 2011 Ifremer, Codelutin, Chatellier Eric * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as Modified: trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/ResultHandler.java =================================================================== --- trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/ResultHandler.java 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/ResultHandler.java 2011-01-14 14:05:29 UTC (rev 505) @@ -3,7 +3,7 @@ * $Id$ * $HeadURL$ * %% - * Copyright (C) 2010 Ifremer, Codelutin, Chatellier Eric + * Copyright (C) 2010 - 2011 Ifremer, Codelutin, Chatellier Eric * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as @@ -25,18 +25,24 @@ import static org.nuiton.i18n.I18n._; +import java.io.File; +import java.util.ArrayList; import java.util.Collection; +import java.util.Date; +import java.util.List; +import javax.swing.JFileChooser; import javax.swing.JOptionPane; +import javax.swing.JTextField; import javax.swing.SwingWorker; +import jaxx.runtime.JAXXUtil; + import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import fr.ifremer.coser.CoserBusinessException; import fr.ifremer.coser.CoserException; -import fr.ifremer.coser.services.ProjectService; +import fr.ifremer.coser.services.WebService; import fr.ifremer.coser.ui.common.CommonHandler; import fr.ifremer.coser.ui.util.CoserProgressBar; @@ -51,62 +57,187 @@ */ public class ResultHandler extends CommonHandler { - private static final Log log = LogFactory.getLog(ResultHandler.class); + /** + * Initialise la vue (principalement en recuperant les données. + * + * @param view view + */ + public void init(SelectUploadResultView view) { + //SwingUtil.fixTableColumnWidth(view.getSelectedProjectTable(), 1, 25); + //SwingUtil.fixTableColumnWidth(view.getAvailableProjectTable(), 1, 25); + view.getAvailableProjectTable().setDefaultRenderer(String[].class, new RsufiResultRenderer()); + + // initialise les données avec les filtres par default + updateAvailableResultsFilter(view); + + } + /** - * Perform file upload to coser server after selection by user. + * Met à jour les données de la table apres la modification d'un + * ou plusieurs filtre. * * @param view view */ - public void performResultUpload(final SelectUploadResultView view) { + public void updateAvailableResultsFilter(SelectUploadResultView view) { + + // get filter + Date beginDate = view.getFilterBeginDate().getDate(); + Date endDate = view.getFilterEndDate().getDate(); + boolean onlyPubliable = view.getPubliableResults().isSelected(); - int response = JOptionPane.showConfirmDialog(view, _("coser.ui.uploadresult.confirmupload"), _("coser.ui.uploadresult.title"), - JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); + // get result + WebService webService = view.getContextValue(WebService.class); - if (response == JOptionPane.YES_OPTION) { - - // get result selected by user - final Collection<String[]> selectedResult = view.getSelectedProjectTableModel().getSelectedResult(); - if (CollectionUtils.isNotEmpty(selectedResult)) { + try { + List<Object[]> results = webService.findAllProjectWithResult(beginDate, endDate, onlyPubliable); + view.getAvailableProjectTableModel().setResultPath(results); + } catch (CoserBusinessException ex) { + throw new CoserException("Can't get results", ex); + } + } - SwingWorker<Void, Void> task = new SwingWorker<Void, Void>() { + /** + * Add selected result in available table to selected table. + * + * @param view view + */ + public void addAvailableResult(SelectUploadResultView view) { + + // get new result to add + List<Object[]> newResult = new ArrayList<Object[]>(); + int[] selectedAvailableRows = view.getAvailableProjectTable().getSelectedRows(); + for (int selectedAvailableRow : selectedAvailableRows) { + Object[] resultData = view.getAvailableProjectTableModel().getResultPath().get(selectedAvailableRow); + newResult.add(resultData); + } - @Override - protected Void doInBackground() { - - try { - // get progress bar - CoserProgressBar progressBar = view.getUploadProgressBar(); - ProjectService projectService = view.getContextValue(ProjectService.class); - projectService.performResultUpload(selectedResult, progressBar); - } - catch (CoserBusinessException ex) { - throw new CoserException("Can't send results", ex); - } - return null; + // les collisions ne peuvent pas être détecté a ce moment. + // seulement lors du clic sur le bouton export/upload + + // add new results + List<Object[]> currentResult = view.getSelectedProjectTableModel().getResultPath(); + currentResult.addAll(newResult); + view.getAvailableProjectTableModel().setResultPath(currentResult); + } + + /** + * Remove selected result from selected list. + * + * @param view view + */ + public void removeSelectedResult(SelectUploadResultView view) { + List<Object[]> currentResult = view.getSelectedProjectTableModel().getResultPath(); + int[] selectedSelectedRows = view.getSelectedProjectTable().getSelectedRows(); + for (int selectedSelectedRow : selectedSelectedRows) { + currentResult.remove(selectedSelectedRow); + } + view.getAvailableProjectTableModel().setResultPath(currentResult); + } + + /** + * Perform file upload to coser server after selection by user. + * + * @param view view + */ + public void performUploadResult(final ExportUploadDialog view) { + + // get authen options + final String login = view.getUploadLogintextField().getText(); + final String password = new String(view.getUploadPasswordtextField().getPassword()); + + // get result selected by user + SelectUploadResultView parentView = view.getContextValue(SelectUploadResultView.class, JAXXUtil.PARENT); + final Collection<Object[]> selectedResult = parentView.getSelectedProjectTableModel().getResultPath(); + if (CollectionUtils.isNotEmpty(selectedResult)) { + + SwingWorker<Void, Void> task = new SwingWorker<Void, Void>() { + @Override + protected Void doInBackground() { + try { + // get progress bar + CoserProgressBar progressBar = view.getUploadProgressBar(); + WebService webService = view.getContextValue(WebService.class); + webService.performResultUpload(selectedResult, login, password, progressBar); } - - @Override - protected void done() { + catch (CoserBusinessException ex) { + throw new CoserException("Can't send results", ex); + } + return null; + } - // laisser cet appel, sinon les exceptions sont silencieuse - try { - get(); - } catch (Exception ex) { - throw new CoserException("Can't send results", ex); - } + @Override + protected void done() { - JOptionPane.showMessageDialog(view, _("coser.ui.uploadresult.resultsuploaded"), - _("coser.ui.uploadresult.title"), JOptionPane.INFORMATION_MESSAGE); + // laisser cet appel, sinon les exceptions sont silencieuse + try { + get(); + } catch (Exception ex) { + throw new CoserException("Can't send results", ex); } - }; - task.execute(); - } + + JOptionPane.showMessageDialog(view, _("coser.ui.uploadresult.resultsuploaded"), + _("coser.ui.uploadresult.title"), JOptionPane.INFORMATION_MESSAGE); + } + }; + task.execute(); } - else { - if (log.isDebugEnabled()) { - log.debug("Upload result skipped"); - } + } + + /** + * Perform file upload to coser server after selection by user. + * + * @param view view + */ + public void performExtractResult(ExportUploadDialog view) { + + // get extract directory + String extractPath = view.getExtractToTextField().getText(); + File extractDirectory = new File(extractPath); + + // get source data option + boolean withData = view.getSourceDataExport().isSelected(); + + SelectUploadResultView parentView = view.getContextValue(SelectUploadResultView.class, JAXXUtil.PARENT); + Collection<Object[]> selectedResult = parentView.getSelectedProjectTableModel().getResultPath(); + WebService webService = view.getContextValue(WebService.class); + try { + webService.performResultExtract(selectedResult, extractDirectory, withData); + JOptionPane.showMessageDialog(view, _("coser.ui.uploadresult.resultsextracted"), + _("coser.ui.uploadresult.title"), JOptionPane.INFORMATION_MESSAGE); } + catch (CoserBusinessException ex) { + throw new CoserException("Can't upload results", ex); + } + } + + /** + * Just display export / upload dialog. + * + * @param view parent view + */ + public void showExportUploadDialog(SelectUploadResultView view) { + ExportUploadDialog dialog = new ExportUploadDialog(view); + dialog.setHandler(this); + dialog.setLocationRelativeTo(view); + dialog.setVisible(true); + } + + /** + * Select result file (directory only). + * + * @param view view + * @param textComponent text component to set selected file + */ + public void selectExportDirectory(ExportUploadDialog view, JTextField textComponent) { + JFileChooser selectFileChooser = getFileChooserInstance(); + selectFileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + + int result = selectFileChooser.showOpenDialog(view); + if (result == JFileChooser.APPROVE_OPTION) { + File selectedFile = selectFileChooser.getSelectedFile(); + textComponent.setText(selectedFile.getAbsolutePath()); + } + } } Modified: trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/ResultTableModel.java =================================================================== --- trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/ResultTableModel.java 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/ResultTableModel.java 2011-01-14 14:05:29 UTC (rev 505) @@ -3,7 +3,7 @@ * $Id$ * $HeadURL$ * %% - * Copyright (C) 2010 Ifremer, Codelutin, Chatellier Eric + * Copyright (C) 2010 - 2011 Ifremer, Codelutin, Chatellier Eric * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as Modified: trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/RsufiResultRenderer.java =================================================================== --- trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/RsufiResultRenderer.java 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/RsufiResultRenderer.java 2011-01-14 14:05:29 UTC (rev 505) @@ -3,7 +3,7 @@ * $Id$ * $HeadURL$ * %% - * Copyright (C) 2010 Ifremer, Codelutin, Chatellier Eric + * Copyright (C) 2010 - 2011 Ifremer, Codelutin, Chatellier Eric * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as @@ -28,10 +28,12 @@ import javax.swing.JTable; import javax.swing.table.DefaultTableCellRenderer; -import org.apache.commons.lang.StringUtils; +import fr.ifremer.coser.bean.Project; +import fr.ifremer.coser.bean.RSufiResult; +import fr.ifremer.coser.bean.Selection; /** - * TODO add comment here. + * Available and selected result path renderer. * * @author chatellier * @version $Revision$ @@ -49,9 +51,12 @@ boolean isSelected, boolean hasFocus, int row, int column) { Object localValue = value; - if (value instanceof String[]) { - String[] arrayValue = (String[])value; - localValue = StringUtils.join(arrayValue, '/'); + if (value instanceof Object[]) { + Object[] arrayValue = (Object[])value; + //localValue = StringUtils.join(arrayValue, '/'); + localValue = ((Project)arrayValue[0]).getName() + "/" + + ((Selection)arrayValue[1]).getName() + "/" + + ((RSufiResult)arrayValue[2]).getName(); } return super.getTableCellRendererComponent(table, localValue, isSelected, hasFocus, row, column); Modified: trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/RsufiResultTreeModel.java =================================================================== --- trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/RsufiResultTreeModel.java 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/RsufiResultTreeModel.java 2011-01-14 14:05:29 UTC (rev 505) @@ -3,7 +3,7 @@ * $Id$ * $HeadURL$ * %% - * Copyright (C) 2010 Ifremer, Codelutin, Chatellier Eric + * Copyright (C) 2010 - 2011 Ifremer, Codelutin, Chatellier Eric * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as @@ -25,12 +25,15 @@ import static org.nuiton.i18n.I18n._; +import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.swing.table.AbstractTableModel; +import fr.ifremer.coser.bean.RSufiResult; + /** * Model represantant la liste de tous les resultats rsufi present * dans le dossier de stockage de coser, tous projets confondu. @@ -46,20 +49,41 @@ /** serialVersionUID. */ private static final long serialVersionUID = 6404018386062830677L; - protected List<String[]> resultPath; + /** Les données de la table. */ + protected List<Object[]> resultPath; - protected Set<String[]> selectedResult; - - public void setResultPath(List<String[]> resultPath) { + /** Les résultats marqué comme étant des données de map. */ + protected Set<Object[]> mapResult; + + /** Les résultat dont la publication des données est autorisée. */ + protected Set<Object[]> publishDataResult; + + /** Selected table tablemodel (do not show all columns). */ + protected boolean selected; + + public RsufiResultTreeModel(boolean selected) { + this.selected = selected; + } + + public void setResultPath(List<Object[]> resultPath) { this.resultPath = resultPath; - selectedResult = new HashSet<String[]>(); + mapResult = new HashSet<Object[]>(); + publishDataResult = new HashSet<Object[]>(); fireTableDataChanged(); } - public Set<String[]> getSelectedResult() { - return selectedResult; + public List<Object[]> getResultPath() { + return resultPath; } + public Set<Object[]> getMapResult() { + return mapResult; + } + + public Set<Object[]> getPublishDataResult() { + return publishDataResult; + } + /* * @see javax.swing.table.TableModel#getRowCount() */ @@ -77,11 +101,17 @@ String result = null; switch(column) { case 0: - result = _("coser.ui.uploadresult.path"); + result = _("coser.ui.uploadresult.creationDate"); break; case 1: - result = _("coser.ui.uploadresult.selected"); + result = _("coser.ui.uploadresult.path"); break; + case 2: + result = _("coser.ui.uploadresult.mapResult"); + break; + case 3: + result = _("coser.ui.uploadresult.publishData"); + break; } return result; } @@ -91,11 +121,17 @@ Class<?> result = null; switch(columnIndex) { case 0: + result = Date.class; + break; + case 1: result = String[].class; break; - case 1: + case 2: result = Boolean.class; break; + case 3: + result = Boolean.class; + break; } return result; } @@ -105,7 +141,11 @@ */ @Override public int getColumnCount() { - return 2; + int result = 2; + if (selected) { + result = 4; + } + return result; } /* @@ -116,15 +156,25 @@ Object result = null; - String[] data = resultPath.get(rowIndex); + Object[] data = resultPath.get(rowIndex); switch (columnIndex) { case 0: + RSufiResult rsufiResult = (RSufiResult)data[2]; + result = rsufiResult.getCreationDate(); + break; + case 1: result = data; break; - case 1: + case 2: // c'est pas tres safe tu les hashcode des tableaux // mais bon... - result = selectedResult.contains(data); + result = mapResult.contains(data); + break; + case 3: + // c'est pas tres safe tu les hashcode des tableaux + // mais bon... + result = publishDataResult.contains(data); + break; } return result; @@ -132,20 +182,31 @@ @Override public boolean isCellEditable(int rowIndex, int columnIndex) { - return columnIndex == 1; + return columnIndex >= 1; } @Override public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + + Object[] data = resultPath.get(rowIndex); + + if (columnIndex == 2) { + Boolean bValue = (Boolean)aValue; + if (bValue.booleanValue()) { + mapResult.add(data); + } + else { + mapResult.remove(data); + } + } - if (aValue instanceof Boolean) { - String[] data = resultPath.get(rowIndex); + else if (columnIndex == 3) { Boolean bValue = (Boolean)aValue; if (bValue.booleanValue()) { - selectedResult.add(data); + publishDataResult.add(data); } else { - selectedResult.remove(data); + publishDataResult.remove(data); } } } Modified: trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/SelectUploadResultView.jaxx =================================================================== --- trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/SelectUploadResultView.jaxx 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/SelectUploadResultView.jaxx 2011-01-14 14:05:29 UTC (rev 505) @@ -5,7 +5,7 @@ $Id$ $HeadURL$ %% - Copyright (C) 2010 Ifremer, Codelutin, Chatellier Eric + Copyright (C) 2010 - 2011 Ifremer, Codelutin, Chatellier Eric %% This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -31,22 +31,78 @@ </cell> </row> <row> - <cell weightx="1" fill="both"> + <cell weightx="1" fill="horizontal"> + <JLabel text="coser.ui.uploadresult.availableResults" /> + </cell> + </row> + <row> + <cell weightx="1" fill="horizontal"> + <Table> + <row> + <cell> + <JLabel text="coser.ui.uploadresult.filter.beginDate" /> + </cell> + <cell> + <JXDatePicker id="filterBeginDate" + onActionPerformed="getHandler().updateAvailableResultsFilter(this)" /> + </cell> + <cell> + <JLabel text="coser.ui.uploadresult.filter.endDate" /> + </cell> + <cell> + <JXDatePicker id="filterEndDate" + onActionPerformed="getHandler().updateAvailableResultsFilter(this)" /> + </cell> + <cell> + <JLabel text="coser.ui.uploadresult.filter.publiableResults" /> + </cell> + <cell> + <JCheckBox id="publiableResults" selected="true" + onActionPerformed="getHandler().updateAvailableResultsFilter(this)" /> + </cell> + </row> + </Table> + </cell> + </row> + <row> + <cell weightx="1" weighty="1" fill="both"> <JScrollPane> - <RsufiResultTreeModel id="selectedProjectTableModel" /> - <JTable id="selectedProjectTable" model="{getSelectedProjectTableModel()}"/> + <RsufiResultTreeModel id="availableProjectTableModel" initializer='new RsufiResultTreeModel(false)' + onTableChanged='addResultButton.setEnabled(getAvailableProjectTableModel().getRowCount() == 0)'/> + <JTable id="availableProjectTable" model="{getAvailableProjectTableModel()}"/> </JScrollPane> </cell> </row> <row> - <cell weightx="1" anchor="east"> - <JButton text="coser.ui.uploadresult.upload" - onActionPerformed="getHandler().performResultUpload(this)"/> + <cell weightx="1" anchor="center"> + <JButton id="addResultButton" text="coser.ui.uploadresult.addResults" + onActionPerformed="getHandler().addAvailableResult(this)" /> </cell> </row> <row> <cell weightx="1" fill="horizontal"> - <fr.ifremer.coser.ui.util.CoserProgressBar id="uploadProgressBar" stringPainted="true" /> + <JLabel text="coser.ui.uploadresult.selectedResults" /> </cell> </row> + <row> + <cell weightx="1" weighty="1" fill="both"> + <JScrollPane> + <RsufiResultTreeModel id="selectedProjectTableModel" initializer='new RsufiResultTreeModel(true)' + onTableChanged='removeResultButton.setEnabled(getAvailableProjectTableModel().getRowCount() == 0)'/> + <JTable id="selectedProjectTable" model="{getSelectedProjectTableModel()}"/> + </JScrollPane> + </cell> + </row> + <row> + <cell weightx="1" anchor="center"> + <JButton id="removeResultButton" text="coser.ui.uploadresult.removeResults" + onActionPerformed="getHandler().removeSelectedResult(this)"/> + </cell> + </row> + <row> + <cell weightx="1" anchor="east"> + <JButton text="coser.ui.uploadresult.exportupload" + onActionPerformed="getHandler().showExportUploadDialog(this)"/> + </cell> + </row> </Table> Modified: trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/SelectionAddResultDialog.jaxx =================================================================== --- trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/SelectionAddResultDialog.jaxx 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/SelectionAddResultDialog.jaxx 2011-01-14 14:05:29 UTC (rev 505) @@ -63,11 +63,20 @@ </row> <row> <cell anchor="west"> + <JLabel text="coser.ui.result.creationDate" /> + </cell> + <cell fill="horizontal" columns="2"> + <JXDatePicker id="resultCreationDate" date="{new java.util.Date()}" + onActionPerformed="getRsufiResult().setCreationDate(resultCreationDate.getDate())"/> + </cell> + </row> + <row> + <cell anchor="west"> <JLabel text="coser.ui.result.zone" /> </cell> <cell fill="horizontal" columns="2"> <JComboBox id="resultZoneCombo" model="{new ZoneComboBoxModel(this)}" - renderer="{new ZoneComboBoxRenderer(this)}" + renderer="{new ZoneComboBoxRenderer()}" onActionPerformed='getRsufiResult().setZone((String)resultZoneCombo.getSelectedItem())'/> </cell> </row> Modified: trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/ZoneComboBoxModel.java =================================================================== --- trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/ZoneComboBoxModel.java 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/ZoneComboBoxModel.java 2011-01-14 14:05:29 UTC (rev 505) @@ -5,7 +5,7 @@ * $Id$ * $HeadURL$ * %% - * Copyright (C) 2011 Codelutin, Chatellier Eric + * Copyright (C) 2011 Ifremer, Codelutin, Chatellier Eric * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as @@ -25,15 +25,12 @@ package fr.ifremer.coser.ui.result; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - import javax.swing.DefaultComboBoxModel; import fr.ifremer.coser.CoserBusinessException; import fr.ifremer.coser.CoserException; import fr.ifremer.coser.services.WebService; +import fr.ifremer.coser.storage.DataStorage; /** * Zone combo box model. @@ -51,19 +48,16 @@ /** serialVersionUID. */ private static final long serialVersionUID = 4452070553401468762L; - public SelectionAddResultDialog view; + protected SelectionAddResultDialog view; - public List<String> zonesIds; + protected DataStorage zonesMap; - public Map<String, String[]> zonesMap; - public ZoneComboBoxModel(SelectionAddResultDialog view) { this.view = view; WebService webService = view.getContextValue(WebService.class); try { zonesMap = webService.getZonesMap(); - zonesIds = new ArrayList<String>(zonesMap.keySet()); } catch (CoserBusinessException ex) { throw new CoserException("Can't get zone list", ex); } @@ -71,15 +65,23 @@ @Override public int getSize() { - return zonesIds.size(); + // -1 for header + return zonesMap.size() - 1; } @Override public Object getElementAt(int index) { - return zonesIds.get(index); + // "id";"facade";"zone";"periode";"serie";"comment";"map" + // +1 for header + return zonesMap.get(index + 1)[0]; } - + public String[] getZone(String zoneId) { - return zonesMap.get(zoneId); + int index = zonesMap.indexOf(zoneId); + String[] result = null; + if (index != -1) { + result = zonesMap.get(index); + } + return result; } } Modified: trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/ZoneComboBoxRenderer.java =================================================================== --- trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/ZoneComboBoxRenderer.java 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/result/ZoneComboBoxRenderer.java 2011-01-14 14:05:29 UTC (rev 505) @@ -5,7 +5,7 @@ * $Id$ * $HeadURL$ * %% - * Copyright (C) 2011 Codelutin, Chatellier Eric + * Copyright (C) 2011 Ifremer, Codelutin, Chatellier Eric * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as @@ -30,9 +30,6 @@ import javax.swing.DefaultListCellRenderer; import javax.swing.JList; -import fr.ifremer.coser.bean.Selection; -import fr.ifremer.coser.services.ProjectService; - /** * Zone list combo renderer (display zone name for zone id). * @@ -47,27 +44,21 @@ /** serialVersionUID. */ private static final long serialVersionUID = -8231189755539976714L; - protected String surveyName; - - public ZoneComboBoxRenderer(SelectionAddResultDialog view) { - ProjectService projectService = view.getContextValue(ProjectService.class); - Selection selection = view.getContextValue(Selection.class); - surveyName = projectService.getProjectSurveyName(selection); - } - @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { String zoneId = (String)value; ZoneComboBoxModel model = (ZoneComboBoxModel)list.getModel(); - String[] zoneInfo = model.getZone(zoneId); + + // "id";"facade";"zone";"periode";"serie";"comment";"map" + String[] zoneData = model.getZone(zoneId); String zoneName = null; - if (zoneInfo != null) { + if (zoneData != null) { // le surveyName ne sert à rien // mais est la a titre d'information par rapport // à l'affichage cote web - zoneName = zoneInfo[0] + " - " + zoneInfo[1] + " - " + surveyName; + zoneName = zoneData[1] + " - " + zoneData[2] + " - " + zoneData[3] + " - " + zoneData[4]; } else { zoneName = zoneId; Modified: trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/selection/SelectionDetailsView.jaxx =================================================================== --- trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/selection/SelectionDetailsView.jaxx 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/selection/SelectionDetailsView.jaxx 2011-01-14 14:05:29 UTC (rev 505) @@ -5,7 +5,7 @@ $Id$ $HeadURL$ %% - Copyright (C) 2010 Ifremer, Codelutin, Chatellier Eric + Copyright (C) 2010 - 2011 Ifremer, Codelutin, Chatellier Eric %% This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -132,7 +132,7 @@ </cell> <cell anchor="south"> <JButton id="validDatesButton" text="coser.ui.selection.details.validYears" - onActionPerformed="getHandler().updateSelectionYearsData(this);setYearsValidated(true)" + onActionPerformed="getHandler().updateSelectionYearsData(this, false);setYearsValidated(true)" enabled="{!isYearsValidated()}"/> </cell> </row> @@ -168,7 +168,7 @@ <row> <cell anchor="south" columns="2"> <JButton id="validStrataButton" text="coser.ui.selection.details.validStrata" - onActionPerformed="getHandler().strataListChanged(this);setStrataValidated(true)" + onActionPerformed="getHandler().updateSelectionStrataData(this, false);setStrataValidated(true)" enabled="{isYearsValidated() && !isStrataValidated()}"/> </cell> </row> Modified: trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/selection/SelectionHandler.java =================================================================== --- trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/selection/SelectionHandler.java 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/selection/SelectionHandler.java 2011-01-14 14:05:29 UTC (rev 505) @@ -35,6 +35,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.List; @@ -89,12 +90,6 @@ private static final Log log = LogFactory.getLog(SelectionHandler.class); - /** File chooser de l'export de répertoire. */ - protected JFileChooser exportFileChooser; - - /** File chooser de l'ajout de fichier resultat. */ - protected JFileChooser resultFileChooser; - /** * Appelé sur un changement d'onglet dans l'interface de sélection. * @@ -237,7 +232,7 @@ ((CoserListSelectionModel)detailView.getStrataList().getSelectionModel()).setSelectedObjects(selectedStrata); // details view : fill species list and selection - strataListChanged(detailView); + updateSelectionStrataData(detailView, true); List<String> selectedSpecies = selection.getSelectedSpecies(); detailView.getSelectedSpeciesListModel().setSpecies(selectedSpecies); @@ -291,6 +286,7 @@ * N'affiche pas de message utilsateur dans le cas d'un reload. * * @param view view + * @param reload reload total de la selection (n'affiche pas de message) */ protected void updateSelectionYearsData(SelectionDetailsView view, boolean reload) { Project project = view.getContextValue(Project.class); @@ -335,16 +331,6 @@ throw new CoserException("Can't filters data with specified years", ex); } } - - /** - * Rafraichit la liste des zones suite à la selection des années et affiche - * un message utilsateur. - * - * @param view view - */ - public void updateSelectionYearsData(SelectionDetailsView view) { - updateSelectionYearsData(view, false); - } /** * Init openmap toolbar and openmap layers. @@ -364,11 +350,12 @@ } /** - * Appellé lorsque la selection de la liste des zones a changé. + * Appelé lorsque la selection de la liste des zones a changé. * * @param view view + * @param reload reload total de la selection (n'affiche pas de message) */ - public void strataListChanged(SelectionDetailsView view) { + public void updateSelectionStrataData(SelectionDetailsView view, boolean reload) { if (log.isDebugEnabled()) { log.debug("Zone list selection changed, updating species list"); } @@ -384,6 +371,11 @@ selection.setSelectedStrata(strata); updateSelectionSpecies(view); + + if (!reload) { + JOptionPane.showMessageDialog(view, _("coser.ui.selection.detail.stratavalidated"), + _("coser.ui.selection.selectionTitle"), JOptionPane.INFORMATION_MESSAGE); + } } /** @@ -1101,20 +1093,6 @@ } view.dispose(); } - - /** - * Retourne une unique instance du file chooser pour conserver - * le répertoire de sélection d'un appel sur l'autre. - * - * @return - */ - protected JFileChooser getExportFileChooser() { - if (exportFileChooser == null) { - exportFileChooser = new JFileChooser(); - exportFileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); - } - return exportFileChooser; - } /** * Selectionne le dossier d'extraction. @@ -1123,7 +1101,8 @@ * @param textComponent text component to set selected directory */ public void selectOutputDirectory(SelectionRsufiView view, JTextField textComponent) { - JFileChooser selectFileChooser = getExportFileChooser(); + JFileChooser selectFileChooser = getFileChooserInstance(); + selectFileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); int result = selectFileChooser.showOpenDialog(view); if (result == JFileChooser.APPROVE_OPTION) { @@ -1156,26 +1135,13 @@ } /** - * Retourne une unique instance du file chooser pour conserver - * le répertoire de sélection d'un appel sur l'autre. - * - * @return l'instance a utiliser - */ - protected JFileChooser getResultFileChooser() { - if (resultFileChooser == null) { - resultFileChooser = new JFileChooser(); - } - return resultFileChooser; - } - - /** * Select result file (file only). * * @param view view * @param textComponent text component to set selected file */ public void selectResultFile(SelectionAddResultDialog view, JTextField textComponent) { - JFileChooser selectFileChooser = getResultFileChooser(); + JFileChooser selectFileChooser = getFileChooserInstance(); selectFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); int result = selectFileChooser.showOpenDialog(view); @@ -1192,7 +1158,7 @@ * @param textComponent text component to set selected directory */ public void selectMapsDirectory(SelectionAddResultDialog view, JTextField textComponent) { - JFileChooser selectFileChooser = getResultFileChooser(); + JFileChooser selectFileChooser = getFileChooserInstance(); selectFileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); int result = selectFileChooser.showOpenDialog(view); @@ -1209,7 +1175,7 @@ * @param listComponent list component to set selected file */ public void selectResultFileOrDirectory(SelectionAddResultDialog view, JList listComponent) { - JFileChooser selectFileChooser = getResultFileChooser(); + JFileChooser selectFileChooser = getFileChooserInstance(); selectFileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); int result = selectFileChooser.showOpenDialog(view); Modified: trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/util/ErrorHelper.java =================================================================== --- trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/util/ErrorHelper.java 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/util/ErrorHelper.java 2011-01-14 14:05:29 UTC (rev 505) @@ -109,7 +109,7 @@ * @see org.jdesktop.swingx.error.ErrorReporter#reportError(org.jdesktop.swingx.error.ErrorInfo) */ @Override - public void reportError(ErrorInfo errorInfo) throws NullPointerException { + public void reportError(ErrorInfo errorInfo) { try { String emailTo = coserConfig.getSupportEmail(); @@ -138,7 +138,7 @@ for (String propertyName : propertiesNames) { // security, don't send string containing password : if (!propertyName.contains("pass")) { - message.append("\t" + propertyName + " : " + coserConfig.getOptions().getProperty(propertyName) + "\n"); + message.append("\t" + propertyName + " : " + coserConfig.getOptions().getProperty(propertyName) + "\n"); } } Modified: trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/widgets/ComponentTitledBorder.java =================================================================== --- trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/widgets/ComponentTitledBorder.java 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/widgets/ComponentTitledBorder.java 2011-01-14 14:05:29 UTC (rev 505) @@ -31,7 +31,7 @@ import javax.swing.border.Border; public class ComponentTitledBorder implements Border, MouseListener, SwingConstants { - int offset = 5; + protected int offset = 5; protected Component titleComponent; protected JComponent container; Modified: trunk/coser-ui/src/main/resources/fr/ifremer/coser/bean/RSufiResult-error-validation.xml =================================================================== --- trunk/coser-ui/src/main/resources/fr/ifremer/coser/bean/RSufiResult-error-validation.xml 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-ui/src/main/resources/fr/ifremer/coser/bean/RSufiResult-error-validation.xml 2011-01-14 14:05:29 UTC (rev 505) @@ -51,10 +51,4 @@ <message>coser.ui.result.requiredestPopIndPath</message> </field-validator> </field> - <field name="mapsPath"> - <field-validator type="requiredstring"> - <param name="trim">true</param> - <message>coser.ui.result.requiredmapsPath</message> - </field-validator> - </field> </validators> Modified: trunk/coser-ui/src/main/resources/i18n/coser-ui_en_GB.properties =================================================================== --- trunk/coser-ui/src/main/resources/i18n/coser-ui_en_GB.properties 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-ui/src/main/resources/i18n/coser-ui_en_GB.properties 2011-01-14 14:05:29 UTC (rev 505) @@ -129,6 +129,7 @@ coser.ui.result.addOtherDataFile=Add file coser.ui.result.availableDataTitle=Available results \: coser.ui.result.cancel=Cancel +coser.ui.result.creationDate=Result date \: coser.ui.result.estComIndFile=ESTCOMind file \: coser.ui.result.estPopIndFile=ESTPOPind file \: coser.ui.result.extractDataButton=Extract as Rsufi format @@ -140,7 +141,6 @@ coser.ui.result.publishResult=Publish \: coser.ui.result.requiredestComIndPath=ESTCOMind file is required coser.ui.result.requiredestPopIndPath=ESTPOPind file is required -coser.ui.result.requiredmapsPath=Maps directory is required coser.ui.result.requiredname=Result name is required coser.ui.result.requiredrsufiVersion=Rsufi version is required coser.ui.result.resultName=Result name \: @@ -160,6 +160,7 @@ coser.ui.selection.detail.mainAccordion=Details coser.ui.selection.detail.speciesAccordion=Species coser.ui.selection.detail.strataAccordion=Strata +coser.ui.selection.detail.stratavalidated=Strata validated. coser.ui.selection.detail.yearAccordion=Years coser.ui.selection.detail.yearsvalidated=Years validated. coser.ui.selection.details.addToSelectedListTip=Add selected species to selected species list. @@ -216,13 +217,31 @@ coser.ui.selection.tab.details=Selection details coser.ui.selection.tab.lists=Species lists coser.ui.selection.tab.rsufi=RSufi -coser.ui.uploadresult.confirmupload=Are you sure you want to upload this results ? +coser.ui.uploadresult.addResults=Add results +coser.ui.uploadresult.availableResults=Available results \: +coser.ui.uploadresult.creationDate=Creaction date coser.ui.uploadresult.explanation=Welcome in results server publication interface. Only administrators with password can use this interface. +coser.ui.uploadresult.exportUploadTitle=Export/Upload +coser.ui.uploadresult.exportupload=Extract/Upload +coser.ui.uploadresult.extract=Extract +coser.ui.uploadresult.extractChoice=Extract to directory +coser.ui.uploadresult.extractTo=Extract directory \: +coser.ui.uploadresult.extractWithData=Extract results with sources data +coser.ui.uploadresult.filter.beginDate=Begin date \: +coser.ui.uploadresult.filter.endDate=End date \: +coser.ui.uploadresult.filter.publiableResults=Only publiables results +coser.ui.uploadresult.mapResult=Map result coser.ui.uploadresult.path=Result path +coser.ui.uploadresult.publishData=Allow source data +coser.ui.uploadresult.removeResults=Remove results +coser.ui.uploadresult.resultsextracted=Result extracted. coser.ui.uploadresult.resultsuploaded=Results published. -coser.ui.uploadresult.selected=\u2026 +coser.ui.uploadresult.selectedResults=Selected results \: coser.ui.uploadresult.title=Results publication coser.ui.uploadresult.upload=Send results +coser.ui.uploadresult.uploadChoice=Upload to server +coser.ui.uploadresult.uploadLogin=Admin login \: +coser.ui.uploadresult.uploadPassword=Admin password \: coser.ui.validators.content=Content \: coser.ui.validators.description=Application must be restarted after validators modification. coser.ui.validators.title=Controls Modified: trunk/coser-ui/src/main/resources/i18n/coser-ui_fr_FR.properties =================================================================== --- trunk/coser-ui/src/main/resources/i18n/coser-ui_fr_FR.properties 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-ui/src/main/resources/i18n/coser-ui_fr_FR.properties 2011-01-14 14:05:29 UTC (rev 505) @@ -129,6 +129,7 @@ coser.ui.result.addOtherDataFile=Ajouter un fichier coser.ui.result.availableDataTitle=R\u00E9sultats disponibles coser.ui.result.cancel=Annuler +coser.ui.result.creationDate=Date du r\u00E9sultats \: coser.ui.result.estComIndFile=Fichier ESTCOMind \: coser.ui.result.estPopIndFile=Fichier ESTPOPind \: coser.ui.result.extractDataButton=Extraire au format RSufi @@ -140,7 +141,6 @@ coser.ui.result.publishResult=Publication \: coser.ui.result.requiredestComIndPath=Le fichier ESTCOMind est requis coser.ui.result.requiredestPopIndPath=Le fichier ESTPOPind est requis -coser.ui.result.requiredmapsPath=Le dossier des cartes est requis coser.ui.result.requiredname=Le nom du r\u00E9sultat est requis coser.ui.result.requiredrsufiVersion=Le champ 'rsufiVersion' est requis coser.ui.result.resultName=Nom du r\u00E9sultat \: @@ -160,6 +160,7 @@ coser.ui.selection.detail.mainAccordion=D\u00E9tails coser.ui.selection.detail.speciesAccordion=Esp\u00E8ces coser.ui.selection.detail.strataAccordion=Strates +coser.ui.selection.detail.stratavalidated=Strates valid\u00E9es. coser.ui.selection.detail.yearAccordion=Ann\u00E9es coser.ui.selection.detail.yearsvalidated=Ann\u00E9es valid\u00E9es. coser.ui.selection.details.addToSelectedListTip=Ajoute les esp\u00E8ces s\u00E9lectionn\u00E9es \u00E0 la liste des especes s\u00E9lectionn\u00E9es. @@ -216,13 +217,31 @@ coser.ui.selection.tab.details=D\u00E9tails de la s\u00E9lection coser.ui.selection.tab.lists=Listes des esp\u00E8ces coser.ui.selection.tab.rsufi=RSufi -coser.ui.uploadresult.confirmupload=\u00CAtes vous s\u00FBr de vouloir publier ces r\u00E9sultats ? +coser.ui.uploadresult.addResults=Ajouter le r\u00E9sultat +coser.ui.uploadresult.availableResults=R\u00E9sultats disponible \: +coser.ui.uploadresult.creationDate=Date de cr\u00E9ation coser.ui.uploadresult.explanation=Bienvenue dans l'interface de s\u00E9lection des r\u00E9sultats \u00E0 envoyer sur le serveur Coser. Seul les administrateurs disposant du mot de passe peuvent effectuer cette action. +coser.ui.uploadresult.exportUploadTitle=Exporter/Uploader +coser.ui.uploadresult.exportupload=Exporter/Uploader +coser.ui.uploadresult.extract=Extraire +coser.ui.uploadresult.extractChoice=Extraire vers un dossier +coser.ui.uploadresult.extractTo=Dossier d'extraction \: +coser.ui.uploadresult.extractWithData=Extraire les r\u00E9sultats avec les donn\uFFFDes sources +coser.ui.uploadresult.filter.beginDate=Date de d\u00E9but \: +coser.ui.uploadresult.filter.endDate=Date de fin \: +coser.ui.uploadresult.filter.publiableResults=Seulement les r\u00E9sultats publiables +coser.ui.uploadresult.mapResult=R\u00E9sultat de cartes coser.ui.uploadresult.path=Chemin du r\u00E9sultats +coser.ui.uploadresult.publishData=Autoriser les sources +coser.ui.uploadresult.removeResults=Supprimer le r\u00E9sultat +coser.ui.uploadresult.resultsextracted=R\u00E9sultats extraits. coser.ui.uploadresult.resultsuploaded=R\u00E9sultats publi\u00E9s. -coser.ui.uploadresult.selected=\u2026 +coser.ui.uploadresult.selectedResults=R\u00E9sultats s\u00E9lectionn\u00E9s \: coser.ui.uploadresult.title=Publication des r\u00E9sultats coser.ui.uploadresult.upload=Envoyer les r\u00E9sultats +coser.ui.uploadresult.uploadChoice=Envoyer sur le serveur +coser.ui.uploadresult.uploadLogin=Login admin \: +coser.ui.uploadresult.uploadPassword=Mot de passe admin \: coser.ui.validators.content=Contenu \: coser.ui.validators.description=L'application doit \u00EAtre red\u00E9marr\u00E9e apr\u00E8s la modification des validateurs. coser.ui.validators.title=Contr\u00F4les Modified: trunk/coser-web/src/main/java/fr/ifremer/coser/web/CoserWebConfig.java =================================================================== --- trunk/coser-web/src/main/java/fr/ifremer/coser/web/CoserWebConfig.java 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-web/src/main/java/fr/ifremer/coser/web/CoserWebConfig.java 2011-01-14 14:05:29 UTC (rev 505) @@ -57,22 +57,22 @@ } /** - * Get admin password. + * Get admin login. * - * @return admin password + * @return admin login */ - public String getAdminPassword() { - String result = getOption(CoserWebOption.ADMIN_PASSWORD.key); + public String getAdminLogin() { + String result = getOption(CoserWebOption.ADMIN_LOGIN.key); return result; } /** - * Get eastwood server url to use. + * Get admin password. * - * @return eastwood context url + * @return admin password */ - public String getEastWoodUrl() { - String result = getOption(CoserWebOption.EASTWOOD_URL.key); + public String getAdminPassword() { + String result = getOption(CoserWebOption.ADMIN_PASSWORD.key); return result; } @@ -80,8 +80,8 @@ CONFIG_FILE(CONFIG_FILE_NAME, _("coser.config.config.file.description"), "coserweb.properties"), ADMIN_EMAIL("coser.admin.email", _("coser.config.config.file.description"), "harmonie at ifremer.fr"), - ADMIN_PASSWORD("coser.admin.password", _("coser.config.admin.password.description"), null), - EASTWOOD_URL("coser.eastwood.url", _("coser.config.eastwood.url.description"), "http://www.ifremer.fr/eastwood"); + ADMIN_LOGIN("coser.admin.login", _("coser.config.admin.login.description"), null), + ADMIN_PASSWORD("coser.admin.password", _("coser.config.admin.password.description"), null); protected String key; protected String description; Modified: trunk/coser-web/src/main/java/fr/ifremer/coser/web/actions/UploadResultAction.java =================================================================== --- trunk/coser-web/src/main/java/fr/ifremer/coser/web/actions/UploadResultAction.java 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-web/src/main/java/fr/ifremer/coser/web/actions/UploadResultAction.java 2011-01-14 14:05:29 UTC (rev 505) @@ -34,6 +34,7 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.nuiton.util.StringUtil; import com.opensymphony.xwork2.Action; @@ -61,38 +62,49 @@ private static final Log log = LogFactory.getLog(UploadResultAction.class); - private File resultFile; + protected File resultFile; - private String password; + protected String login; + protected String sha1Password; + + public File getResultFile() { + return resultFile; + } + public void setResultFile(File resultFile) { this.resultFile = resultFile; } - public void setPassword(String password) { - this.password = password; + public String getLogin() { + return login; } - public File getResultFile() { - return resultFile; + public void setLogin(String login) { + this.login = login; } - public String getPassword() { - return password; + public void setSha1Password(String sha1Password) { + this.sha1Password = sha1Password; } + public String getSha1Password() { + return sha1Password; + } + public String execute() { // check CoserWebConfig config = ServiceFactory.getCoserConfig(); - if (config.getAdminPassword() == null) { + if (config.getAdminPassword() == null || config.getAdminLogin() == null) { if (log.isWarnEnabled()) { log.warn("No admin password set, cannot enable result upload"); } } else { - if (config.getAdminPassword().equals(password)) { + String configSha1Password = StringUtil.encodeSHA1(config.getAdminPassword()); + if (config.getAdminLogin().equals(login) && configSha1Password.equals(sha1Password)) { if (resultFile != null) { WebService webService = ServiceFactory.getWebService(); try { @@ -112,7 +124,7 @@ } else { if (log.isWarnEnabled()) { - log.warn("Wrong password"); + log.warn("Wrong login/password : login = " + login); } } } Modified: trunk/coser-web/src/main/resources/i18n/coser-web_en_GB.properties =================================================================== --- trunk/coser-web/src/main/resources/i18n/coser-web_en_GB.properties 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-web/src/main/resources/i18n/coser-web_en_GB.properties 2011-01-14 14:05:29 UTC (rev 505) @@ -1,3 +1,3 @@ +coser.config.admin.login.description= coser.config.admin.password.description= coser.config.config.file.description= -coser.config.eastwood.url.description= Modified: trunk/coser-web/src/main/resources/i18n/coser-web_fr_FR.properties =================================================================== --- trunk/coser-web/src/main/resources/i18n/coser-web_fr_FR.properties 2011-01-12 15:54:25 UTC (rev 504) +++ trunk/coser-web/src/main/resources/i18n/coser-web_fr_FR.properties 2011-01-14 14:05:29 UTC (rev 505) @@ -1,3 +1,3 @@ +coser.config.admin.login.description= coser.config.admin.password.description= coser.config.config.file.description= -coser.config.eastwood.url.description=