@Before public void setUp() throws Exception { taxonGroup = new TaxonGroup(); taxonGroup.setName("Birds"); taxonGroup = taxaDAO.save(taxonGroup); speciesA = new IndicatorSpecies(); speciesA.setCommonName("Indicator Species A"); speciesA.setScientificName("Indicator Species A"); speciesA.setTaxonGroup(taxonGroup); speciesA = taxaDAO.save(speciesA); speciesB = new IndicatorSpecies(); speciesB.setCommonName("Indicator Species B"); speciesB.setScientificName("Indicator Species B"); speciesB.setTaxonGroup(taxonGroup); speciesB = taxaDAO.save(speciesB); List<Attribute> attributeList = new ArrayList<Attribute>(); Attribute attr; for (AttributeType attrType : AttributeType.values()) { for (AttributeScope scope : new AttributeScope[] {AttributeScope.RECORD, AttributeScope.SURVEY, null}) { attr = new Attribute(); attr.setRequired(true); attr.setName(attrType.toString()); attr.setTypeCode(attrType.getCode()); attr.setScope(scope); attr.setTag(false); if (AttributeType.STRING_WITH_VALID_VALUES.equals(attrType)) { List<AttributeOption> optionList = new ArrayList<AttributeOption>(); for (int i = 0; i < 4; i++) { AttributeOption opt = new AttributeOption(); opt.setValue(String.format("Option %d", i)); opt = taxaDAO.save(opt); optionList.add(opt); } attr.setOptions(optionList); } attr = taxaDAO.save(attr); attributeList.add(attr); } } survey = new Survey(); survey.setName("SingleSiteMultiTaxaSurvey 1234"); survey.setActive(true); survey.setStartDate(new Date()); survey.setDescription("Single Site Multi Taxa Survey Description"); Metadata md = survey.setFormRendererType(SurveyFormRendererType.SINGLE_SITE_MULTI_TAXA); metadataDAO.save(md); survey.setAttributes(attributeList); survey = surveyDAO.save(survey); }
@RolesAllowed({Role.USER, Role.POWERUSER, Role.SUPERVISOR, Role.ADMIN}) @RequestMapping(value = "/bdrs/user/atlas.htm", method = RequestMethod.GET) public ModelAndView addRecord( HttpServletRequest request, HttpServletResponse response, @RequestParam(value = "surveyId", required = true) int surveyId, @RequestParam(value = "taxonSearch", required = false) String taxonSearch, @RequestParam(value = "recordId", required = false, defaultValue = "0") int recordId, @RequestParam(value = "guid", required = false) String guid) { Survey survey = surveyDAO.getSurvey(surveyId); Record record = recordDAO.getRecord(recordId); record = record == null ? new Record() : record; IndicatorSpecies species = null; if (guid != null && !guid.isEmpty()) { species = taxaDAO.getIndicatorSpeciesByGuid(guid); } if (species == null && taxonSearch != null && !taxonSearch.isEmpty()) { List<IndicatorSpecies> speciesList = surveyDAO.getSpeciesForSurveySearch(surveyId, taxonSearch); if (speciesList.isEmpty()) { species = null; } else if (speciesList.size() == 1) { species = speciesList.get(0); } else { log.warn( "Multiple species found for survey " + surveyId + " and taxon search \"" + taxonSearch + "\". Using the first."); species = speciesList.get(0); } } if (species == null && record.getSpecies() != null) { species = record.getSpecies(); } ModelAndView mv; if (species == null) { InputStreamReader reader = null; try { Preference p = preferenceDAO.getPreferenceByKey("ala.species.short.url"); URL url; if (p != null) { url = new URL(p.getValue() + "/" + guid + ".json"); } else { url = new URL( "http://bie.ala.org.au/species/shortProfile/" + guid + ".json"); // fallback to the BIE } URLConnection conn = url.openConnection(); reader = new InputStreamReader(conn.getInputStream()); StringBuffer buff = new StringBuffer(); int c; while ((c = reader.read()) != -1) { buff.append((char) c); } JSONObject ob = JSONObject.fromObject(buff.toString()); IndicatorSpecies taxon = new IndicatorSpecies(); log.debug("Found species information from the atlas : "); log.debug(buff.toString()); // Scientific Name taxon.setScientificName(ob.getString("scientificName")); taxon.setAuthor(ob.getString("author")); taxon.setScientificNameAndAuthor( ob.getString("scientificName") + " " + ob.getString("scientificNameAuthorship")); taxon.setYear(ob.getString("year")); Metadata md = new Metadata(); md.setKey(Metadata.SCIENTIFIC_NAME_SOURCE_DATA_ID); md.setValue(guid); metadataDAO.save(md); taxon.getMetadata().add(md); // Rank TaxonRank rank = TaxonRank.findByIdentifier(ob.getString("rank")); taxon.setTaxonRank(rank); // Common Name taxon.setCommonName(ob.getString("commonName")); md = new Metadata(); md.setKey(Metadata.COMMON_NAME_SOURCE_DATA_ID); md.setValue(ob.getString("commonNameGUID")); metadataDAO.save(md); taxon.getMetadata().add(md); // Group String family = ob.getString("family"); if (family != null) { TaxonGroup g = taxaDAO.getTaxonGroup(family); if (g == null) { g = taxaDAO.createTaxonGroup(family, false, false, false, false, false, true); } taxon.setTaxonGroup(g); } else { TaxonGroup g = taxaDAO.createTaxonGroup("Other", false, false, false, false, false, true); taxon.setTaxonGroup(g); } // Images. // Thumbnail if (ob.containsKey("thumbnail")) { SpeciesProfile sp = new SpeciesProfile(); sp.setType( SpeciesProfile .SPECIES_PROFILE_THUMBNAIL); // this is a 100x100 image, might resize for the // other ones. sp.setHeader("Thumbnail"); sp.setDescription("Thumbnail for " + taxon.getScientificName()); String filename = ob.getString("thumbnail"); String ext = getExtension(filename); ManagedFile mf = new ManagedFile(); mf.setContentType(""); mf.setCredit(""); mf.setLicense(""); mf.setDescription(taxon.getScientificName() + " - " + taxon.getCommonName()); mf.setFilename(mf.getUuid() + ext); mf = managedFileDAO.save(mf); fileService.createFile( mf.getClass(), mf.getId(), mf.getFilename(), downloadFile(new URL(filename))); mf.setContentType(fileService.getFile(mf, mf.getFilename()).getContentType()); managedFileDAO.save(mf); sp.setContent(mf.getUuid()); speciesProfileDAO.save(sp); taxon.getInfoItems().add(sp); // Now thumbnail the thumbnail... BufferedImage fortyXforty = imageService.resizeImage( fileService.getFile(mf, mf.getFilename()).getInputStream(), 40, 40); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ImageIO.write(fortyXforty, "png", baos); baos.flush(); byte[] data = baos.toByteArray(); baos.close(); sp = new SpeciesProfile(); sp.setType( SpeciesProfile .SPECIES_PROFILE_IMAGE_40x40); // this is a 100x100 image, might resize for the // other ones. sp.setHeader("40x40 Thumbnail"); sp.setDescription("40x40 Thumbnail for " + taxon.getScientificName()); mf = new ManagedFile(); mf.setContentType(""); mf.setCredit(""); mf.setLicense(""); mf.setDescription(taxon.getScientificName() + " - " + taxon.getCommonName()); mf.setFilename(mf.getUuid() + ".png"); mf = managedFileDAO.save(mf); fileService.createFile(mf.getClass(), mf.getId(), mf.getFilename(), data); mf.setContentType(fileService.getFile(mf, mf.getFilename()).getContentType()); managedFileDAO.save(mf); sp.setContent(mf.getUuid()); speciesProfileDAO.save(sp); taxon.getInfoItems().add(sp); } // Main Image if (ob.containsKey("imageURL")) { SpeciesProfile sp = new SpeciesProfile(); sp.setType(SpeciesProfile.SPECIES_PROFILE_IMAGE); sp.setHeader("Image"); sp.setDescription("Image for " + taxon.getScientificName()); String filename = ob.getString("imageURL"); String ext = getExtension(filename); ManagedFile mf = new ManagedFile(); mf.setContentType(""); mf.setCredit(""); mf.setLicense(""); mf.setDescription(taxon.getScientificName() + " - " + taxon.getCommonName()); mf.setFilename(mf.getUuid() + ext); mf = managedFileDAO.save(mf); fileService.createFile( mf.getClass(), mf.getId(), mf.getFilename(), downloadFile(new URL(filename))); mf.setContentType(fileService.getFile(mf, mf.getFilename()).getContentType()); managedFileDAO.save(mf); sp.setContent(mf.getUuid()); speciesProfileDAO.save(sp); taxon.getInfoItems().add(sp); } // Save the Taxon species = taxaDAO.save(taxon); } catch (IOException ioe) { log.error("Could not retrieve species profile from the Atlas", ioe); species = null; } finally { if (reader != null) { try { reader.close(); } catch (IOException ioe) { log.error("Error closing stream from Atlas webservice, possible network error", ioe); } } } } if (species == null) { log.debug("Could not determine species, reverting to tracker form"); // The atlas form relies upon a preconfigured species. // If we do not have one, fall back to the tracker form. mv = new ModelAndView(new RedirectView("tracker.htm")); mv.addAllObjects(request.getParameterMap()); mv.addObject("surveyId", surveyId); return mv; } else { // Add all attribute form fields Map<String, FormField> formFieldMap = new HashMap<String, FormField>(); // Add all property form fields for (String propertyName : RECORD_PROPERTY_NAMES) { formFieldMap.put( propertyName, formFieldFactory.createRecordFormField( survey, record, propertyName, species, Taxonomic.TAXONOMIC)); } // Determine the file attribute to use for the form (if there is one) // Sort the list of survey attributes by weight so that we can // correctly select the first file attribute. List<Attribute> attributeList = survey.getAttributes(); Collections.sort(attributeList, new ComparePersistentImplByWeight()); // Retrieve the first file attribute and if present, the associated // record attribute. Attribute fileAttr = null; AttributeValue fileRecAttr = null; for (Attribute attr : attributeList) { if (fileAttr == null && AttributeType.FILE.equals(attr.getType())) { // Attribute found. fileAttr = attr; // Try to locate matching record attribute for (AttributeValue recAttr : record.getAttributes()) { if (fileRecAttr == null && fileAttr.equals(recAttr.getAttribute())) { fileRecAttr = recAttr; } } } } // Map all the existing file attributes to record attributes. Map<Attribute, AttributeValue> fileAttrToRecAttrMap = new HashMap<Attribute, AttributeValue>(); FormField fileFormField = formFieldFactory.createRecordFormField(survey, record, fileAttr, fileRecAttr); Map<String, String> errorMap = (Map<String, String>) getRequestContext().getSessionAttribute("errorMap"); getRequestContext().removeSessionAttribute("errorMap"); Map<String, String> valueMap = (Map<String, String>) getRequestContext().getSessionAttribute("valueMap"); getRequestContext().removeSessionAttribute("valueMap"); Metadata predefinedLocationsMD = survey.getMetadataByKey(Metadata.PREDEFINED_LOCATIONS_ONLY); boolean predefinedLocationsOnly = predefinedLocationsMD != null && Boolean.parseBoolean(predefinedLocationsMD.getValue()); Set<Location> locations = new TreeSet<Location>(new LocationNameComparator()); locations.addAll(survey.getLocations()); if (!predefinedLocationsOnly) { locations.addAll(locationDAO.getUserLocations(getRequestContext().getUser())); } Metadata defaultLocId = getRequestContext().getUser().getMetadataObj(Metadata.DEFAULT_LOCATION_ID); Location defaultLocation; if (defaultLocId == null) { defaultLocation = null; } else { int defaultLocPk = Integer.parseInt(defaultLocId.getValue()); defaultLocation = locationDAO.getLocation(defaultLocPk); } mv = new ModelAndView("atlas"); mv.addObject("record", record); mv.addObject("taxon", species); mv.addObject("survey", survey); mv.addObject("locations", locations); mv.addObject("formFieldMap", formFieldMap); mv.addObject("fileFormField", fileFormField); mv.addObject("preview", request.getParameter("preview") != null); mv.addObject("defaultLocation", defaultLocation); mv.addObject("errorMap", errorMap); mv.addObject("valueMap", valueMap); } return mv; }
protected void parseAttributeValue( String paramKey, String fileKey, Attribute attribute, Map<String, String[]> parameterMap, Map<String, MultipartFile> fileMap, TypedAttributeValue attributeValue) throws ParseException { AttributeType attrType = attribute.getType(); if (attrType == AttributeType.TIME) { // parse out the time attribute if required... duckPunchTimeParameter("", attribute, parameterMap); } String attrValue = getParameter(parameterMap, paramKey); attrFile = fileMap.get(fileKey); if (AttributeType.MULTI_CHECKBOX.equals(attrType) || AttributeType.MULTI_SELECT.equals(attrType) || AttributeType.SINGLE_CHECKBOX.equals(attrType)) { // These types may have a null attrValue and still be valid. addOrUpdateAttribute = true; switch (attrType) { case MULTI_CHECKBOX: addOrUpdateAttribute = true; attributeValue.setMultiCheckboxValue(parameterMap.get(paramKey)); break; case MULTI_SELECT: addOrUpdateAttribute = true; attributeValue.setMultiSelectValue(parameterMap.get(paramKey)); break; case SINGLE_CHECKBOX: // Just clean up the input into "true" or "false" attributeValue.setBooleanValue(Boolean.valueOf(attrValue).toString()); break; default: // Absolutely cannot get here. log.warn("Unknown Attribute Type: " + attribute.getType()); break; } } else if (attrValue != null || attrFile != null) { addOrUpdateAttribute = true; attributeValue.setStringValue(attrValue); switch (attrType) { case TIME: case STRING: case STRING_AUTOCOMPLETE: case TEXT: case BARCODE: case REGEX: case HTML: case HTML_RAW: case HTML_NO_VALIDATION: case HTML_COMMENT: case HTML_HORIZONTAL_RULE: break; case STRING_WITH_VALID_VALUES: addOrUpdateAttribute = !attrValue.isEmpty(); break; case INTEGER: case INTEGER_WITH_RANGE: case DECIMAL: addOrUpdateAttribute = !attrValue.isEmpty(); if (addOrUpdateAttribute) { attributeValue.setNumericValue(new BigDecimal(attrValue)); } break; case DATE: addOrUpdateAttribute = !attrValue.isEmpty(); if (addOrUpdateAttribute) { attributeValue.setDateValue(dateFormat.parse(attrValue)); } break; case IMAGE: case AUDIO: case VIDEO: case FILE: // attrValue is empty when a file is cleared or the client // does not have javascript enabled when uploading a file. // Without javascript, it is not possible to clear a file. // attrFile will always have size zero unless a file // is uploaded. // If there is already a file, but the // record is updated, without changing the file input, // addAttribute will be true but attrFile will // have size zero. addOrUpdateAttribute = (attrValue != null && !attrValue.isEmpty()) || (attrFile != null && attrFile.getSize() > 0); if (addOrUpdateAttribute && attrFile != null && attrFile.getSize() > 0) { attributeValue.setStringValue(attrFile.getOriginalFilename()); } else { // Simplifies the need for users of this class to know about // zero sized files. attrFile = null; } break; case SPECIES: addOrUpdateAttribute = !attrValue.isEmpty(); if (addOrUpdateAttribute) { // Regardless, attrValue should contain the verbatim name. String[] values = parameterMap.get(paramKey); if (values.length > 1 && values[1] != null && StringUtils.hasLength(values[1].trim())) { // use the id to retrieve a species. attributeValue.setStringValue(attrValue); IndicatorSpecies species = null; try { Integer speciesId = Integer.valueOf(values[1]); species = taxaDAO.getIndicatorSpecies(speciesId); } catch (NumberFormatException e) { log.warn("Could not parse string to int for species id", e); } attributeValue.setSpecies(species); } else { // use the name string to search. List<IndicatorSpecies> taxaList = taxaDAO.getIndicatorSpeciesByNameSearchExact(attrValue); // validation has already been done by now so we can just grab the 0th index if it // exists. IndicatorSpecies species = null; if (!taxaList.isEmpty()) { species = taxaList.get(0); } attributeValue.setStringValue(attrValue); attributeValue.setSpecies(species); } } break; case CENSUS_METHOD_ROW: case CENSUS_METHOD_COL: // census method types do not have a string value, but should be added or updated addOrUpdateAttribute = true; attributeValue.setStringValue(""); break; default: log.warn("Unknown Attribute Type: " + attrType); break; } } else if (AttributeType.isCensusMethodType(attrType)) { // census method types do not have a string value, but should be added or updated addOrUpdateAttribute = true; } else { addOrUpdateAttribute = false; } }