package fr.univNantes.geodoc.app.portailmel.services.inner;
import java.awt.geom.Rectangle2D;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.geotoolkit.internal.simple.SimpleReferenceIdentifier;
import org.geotoolkit.metadata.iso.DefaultIdentifier;
import org.geotoolkit.metadata.iso.DefaultMetadata;
import org.geotoolkit.metadata.iso.citation.DefaultCitationDate;
import org.geotoolkit.metadata.iso.citation.DefaultContact;
import org.geotoolkit.metadata.iso.citation.DefaultOnlineResource;
import org.geotoolkit.metadata.iso.citation.DefaultResponsibleParty;
import org.geotoolkit.metadata.iso.distribution.DefaultDigitalTransferOptions;
import org.geotoolkit.metadata.iso.distribution.DefaultDistribution;
import org.geotoolkit.metadata.iso.extent.DefaultExtent;
import org.geotoolkit.metadata.iso.extent.DefaultGeographicBoundingBox;
import org.geotoolkit.metadata.iso.extent.DefaultGeographicDescription;
import org.geotoolkit.metadata.iso.identification.DefaultBrowseGraphic;
import org.geotoolkit.metadata.iso.identification.DefaultRepresentativeFraction;
import org.geotoolkit.util.DefaultInternationalString;
import org.opengis.metadata.Identifier;
import org.opengis.metadata.Metadata;
import org.opengis.metadata.citation.Citation;
import org.opengis.metadata.citation.CitationDate;
import org.opengis.metadata.citation.Contact;
import org.opengis.metadata.citation.DateType;
import org.opengis.metadata.citation.OnLineFunction;
import org.opengis.metadata.citation.OnlineResource;
import org.opengis.metadata.citation.PresentationForm;
import org.opengis.metadata.citation.ResponsibleParty;
import org.opengis.metadata.citation.Role;
import org.opengis.metadata.citation.Series;
import org.opengis.metadata.constraint.Constraints;
import org.opengis.metadata.distribution.Format;
import org.opengis.metadata.extent.Extent;
import org.opengis.metadata.extent.GeographicExtent;
import org.opengis.metadata.identification.AggregateInformation;
import org.opengis.metadata.identification.BrowseGraphic;
import org.opengis.metadata.identification.CharacterSet;
import org.opengis.metadata.identification.DataIdentification;
import org.opengis.metadata.identification.KeywordType;
import org.opengis.metadata.identification.Keywords;
import org.opengis.metadata.identification.Progress;
import org.opengis.metadata.identification.RepresentativeFraction;
import org.opengis.metadata.identification.Resolution;
import org.opengis.metadata.identification.TopicCategory;
import org.opengis.metadata.identification.Usage;
import org.opengis.metadata.maintenance.MaintenanceInformation;
import org.opengis.metadata.maintenance.ScopeCode;
import org.opengis.metadata.spatial.SpatialRepresentationType;
import org.opengis.util.InternationalString;
import org.springframework.stereotype.Component;
import fr.univNantes.geodoc.app.portailmel.model.entities.RecordPortailMEL;
import fr.univNantes.geodoc.model.entities.MotCle;
import fr.univNantes.geodoc.model.entities.Place;
import fr.univNantes.geodoc.services.inner.MetadataConverter;
@Component
public class MetadataConverterPortailMEL implements MetadataConverter<RecordPortailMEL> {
private String host = "localhost:8080";
private String thumbnailUrlStringFormat
= "http://%s/rest/fiches/%s/document/thumbnail";
private String documentUrlStringFormat
= "http://%s/rest/fiches/%s/document/data";
@Override
@SuppressWarnings("serial")
public Metadata recordToMetadata(final RecordPortailMEL record) {
// XXX assert(record.getPlaces().size() > 0);
DefaultMetadata metadata = new DefaultMetadata();
metadata.setFileIdentifier(record.getUUIDMetadata());
metadata.setLanguage(Locale.ENGLISH);
metadata.setCharacterSet(CharacterSet.UTF_8);
metadata.setDateStamp(new Date());
metadata.setHierarchyLevels(
new ArrayList<ScopeCode>() {{ this.add(ScopeCode.DATASET); }}
);
metadata.getContacts().add(new ResponsibleParty() {
@Override
public Role getRole() {
return null;
}
@Override
public InternationalString getPositionName() {
return null;
}
@Override
public InternationalString getOrganisationName() {
return buildI18nString(Locale.FRENCH, record.getOrganismes());
}
@Override
public String getIndividualName() {
return record.getAuteurs();
}
@Override
public Contact getContactInfo() {
try {
if (record.getLien() != null) {
OnlineResource onlineResource
= new DefaultOnlineResource(new URI(record.getLien()));
Contact contact = new DefaultContact(onlineResource);
return contact;
}
} catch (URISyntaxException e) { }
return null;
}
});
metadata.getIdentificationInfo().add(
new DataIdentification() {
@Override
public Collection<Progress> getStatus() {
return null;
}
@Override
public Collection<? extends Usage> getResourceSpecificUsages() {
return null;
}
@Override
public Collection<? extends MaintenanceInformation> getResourceMaintenances() {
return null;
}
@Override
public Collection<? extends Format> getResourceFormats() {
return null;
}
@Override
public Collection<? extends Constraints> getResourceConstraints() {
return null;
}
@Override
public InternationalString getPurpose() {
return null;
}
@Override
public Collection<? extends ResponsibleParty> getPointOfContacts() {
List<ResponsibleParty> parties = new ArrayList<ResponsibleParty>();
parties.add(new DefaultResponsibleParty(Role.PUBLISHER));
return parties;
}
@Override
public Collection<? extends BrowseGraphic> getGraphicOverviews() {
List<BrowseGraphic> graphics = new ArrayList<BrowseGraphic>();
DefaultBrowseGraphic graphic = new DefaultBrowseGraphic();
Map<Locale, String> description = new HashMap<Locale, String>();
description.put(Locale.FRENCH, "vignette");
description.put(Locale.ENGLISH, "thumbnail");
graphic.setFileDescription(new DefaultInternationalString(description));
try {
URI uri = new URI(String.format(thumbnailUrlStringFormat, host, record.getId().toString()));
graphic.setFileName(uri);
} catch (URISyntaxException e) {
// TODO
}
graphics.add(graphic);
return graphics;
}
@Override
public Collection<? extends Keywords> getDescriptiveKeywords() {
ArrayList<Keywords> keywords = new ArrayList<Keywords>();
keywords.add(new Keywords() {
@Override
public KeywordType getType() {
return KeywordType.THEME;
}
@Override
public Citation getThesaurusName() {
return null;
}
@Override
public Collection<? extends InternationalString> getKeywords() {
ArrayList<InternationalString> keywords =
new ArrayList<InternationalString>();
for (final MotCle motCle : record.getMotsCles()) {
Map<Locale, String> keyword = new HashMap<Locale, String>();
keyword.put(Locale.FRENCH, motCle.getLibelle() + " (fr)");
keyword.put(Locale.ENGLISH, motCle.getLibelle() + " (en)");
keywords.add(new DefaultInternationalString(keyword));
}
return keywords;
}
});
return keywords;
}
@Override
public Collection<String> getCredits() {
return null;
}
@Override
public Citation getCitation() {
return new Citation() {
@Override
public InternationalString getTitle() {
return buildI18nString(Locale.FRENCH, record.getTitre());
}
@Override
public Series getSeries() {
return null;
}
@Override
public Collection<PresentationForm> getPresentationForms() {
List<PresentationForm> presentationForms
= new ArrayList<PresentationForm>();
// XXX
presentationForms.add(PresentationForm.DOCUMENT_DIGITAL);
return presentationForms;
}
@Override
public InternationalString getOtherCitationDetails() {
return null;
}
@Override
public Collection<? extends Identifier> getIdentifiers() {
List<Identifier> identifiers = new ArrayList<Identifier>();
identifiers.add(new DefaultIdentifier(record.getUUIDMetadata()));
return identifiers;
}
@Override
public String getISSN() {
return null;
}
@Override
public String getISBN() {
return null;
}
@Override
public Date getEditionDate() {
return null;
}
@Override
public InternationalString getEdition() {
return null;
}
@Override
public Collection<? extends CitationDate> getDates() {
List<CitationDate> dates = new ArrayList<CitationDate>();
dates.add(new DefaultCitationDate(
record.getDateDerniereModification(), DateType.PUBLICATION
));
/*
dates.add(new DefaultCitationDate(
fiche.getDateOrigine(), DateType.CREATION
));
*/
return dates;
}
@Override
public InternationalString getCollectiveTitle() {
return null;
}
@Override
public Collection<? extends ResponsibleParty> getCitedResponsibleParties() {
return null;
}
@Override
public Collection<? extends InternationalString> getAlternateTitles() {
return null;
}
};
}
@Override
public Collection<? extends AggregateInformation> getAggregationInfo() {
return null;
}
@Override
public InternationalString getAbstract() {
return buildI18nString(Locale.FRENCH, record.getDescription());
}
@Override
public Collection<CharacterSet> getCharacterSets() {
return null;
}
@Override
public InternationalString getEnvironmentDescription() {
return null;
}
@Override
public Collection<? extends Extent> getExtents() {
List<GeographicExtent> geographicExtents =
new ArrayList<GeographicExtent>();
Set<String> placesIds = new HashSet<String>();
Rectangle2D wholeBoundingBox = null;
for (Place place : record.getPlaces()) {
Place currentPlace = place;
do {
placesIds.add(currentPlace.id.toString());
currentPlace = currentPlace.parentPlace;
} while (currentPlace != null);
if (place.bounds != null) {
Rectangle2D placeBoundingBox = new Rectangle2D.Double(
place.bounds.minX,
place.bounds.minY,
place.bounds.maxX - place.bounds.minX,
place.bounds.maxY - place.bounds.minY
);
if (wholeBoundingBox == null) {
wholeBoundingBox = placeBoundingBox;
} else {
Rectangle2D.union(wholeBoundingBox, placeBoundingBox, wholeBoundingBox);
}
}
}
if (wholeBoundingBox != null) {
geographicExtents.add(
new DefaultGeographicBoundingBox(wholeBoundingBox)
);
}
for (String placeId : placesIds) {
Identifier identifier = new SimpleReferenceIdentifier(
"http://portailmel.univ-nantes.fr/", placeId
);
geographicExtents.add(new DefaultGeographicDescription(identifier));
}
if (geographicExtents.size() > 0) {
DefaultExtent extent = new DefaultExtent();
extent.setGeographicElements(geographicExtents);
List<Extent> extents = new ArrayList<Extent>();
extents.add(extent);
return extents;
}
return null;
}
@Override
public Collection<Locale> getLanguages() {
return null;
}
@Override
public Collection<SpatialRepresentationType> getSpatialRepresentationTypes() {
Collection<SpatialRepresentationType> types =
new ArrayList<SpatialRepresentationType>();
types.add(SpatialRepresentationType.GRID);
return types;
}
@Override
public Collection<? extends Resolution> getSpatialResolutions() {
List<Resolution> resolutions = new ArrayList<Resolution>();
if (record.getEchelle() != null) {
Resolution resolution = new Resolution() {
@Override
public RepresentativeFraction getEquivalentScale() {
return new DefaultRepresentativeFraction(record.getEchelle());
}
@Override
public Double getDistance() {
return null;
}
};
resolutions.add(resolution);
}
return resolutions;
}
@Override
public InternationalString getSupplementalInformation() {
return null;
}
@Override
public Collection<TopicCategory> getTopicCategories() {
return null;
}
}
);
URI uri = null;
try {
uri = new URI(String.format(documentUrlStringFormat, host, record.getId().toString()));
} catch (URISyntaxException e) {
// TODO
}
DefaultDistribution distribution = new DefaultDistribution();
DefaultDigitalTransferOptions transferOptions = new DefaultDigitalTransferOptions();
transferOptions.setTransferSize(this.round((double)record.getDocument().getTaille() / (1024 * 1024), 2));
DefaultOnlineResource onlineResource = new DefaultOnlineResource();
onlineResource.setLinkage(uri);
onlineResource.setProtocol("WWW:LINK-1.0-http--link");
onlineResource.setName(record.getDocument().getNom());
onlineResource.setFunction(OnLineFunction.DOWNLOAD);
transferOptions.getOnLines().add(onlineResource);
distribution.getTransferOptions().add(transferOptions);
metadata.setDistributionInfo(distribution);
// metadata.getReferenceSystemInfo().add(DefaultGeographicCRS.WGS84);
return metadata;
}
private InternationalString buildI18nString(Locale locale, String text) {
if (text == null) {
return null;
}
Map<Locale, String> map = new HashMap<Locale, String>();
map.put(locale, text);
return new DefaultInternationalString(map);
}
private double round(double value, int n) {
return (Math.round(value * Math.pow(10, n))) / Math.pow(10, n);
}
}