/* * This is eMonocot, a global online biodiversity information resource. * * Copyright © 2011–2015 The Board of Trustees of the Royal Botanic Gardens, Kew and The University of Oxford * * eMonocot is free software: you can redistribute it and/or modify it under the terms of the * GNU Affero General Public License as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * eMonocot is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * The complete text of the GNU Affero General Public License is in the source repository as the file * ‘COPYING’. It is also available from <http://www.gnu.org/licenses/>. */ package org.emonocot.model; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; import javax.persistence.OrderBy; import javax.persistence.Transient; import javax.validation.constraints.Size; import org.apache.solr.common.SolrInputDocument; import org.emonocot.model.constants.MediaType; import org.emonocot.model.marshall.json.TaxonDeserializer; import org.emonocot.model.marshall.json.TaxonSerializer; import org.geotools.geometry.jts.JTSFactoryFinder; import org.hibernate.annotations.Cascade; import org.hibernate.annotations.CascadeType; import org.hibernate.annotations.Type; import org.hibernate.annotations.Where; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.Point; import com.vividsolutions.jts.io.WKTWriter; /** * * @author ben * */ @Entity public class Image extends Multimedia { private static Logger logger = LoggerFactory.getLogger(Image.class); private static final long serialVersionUID = 3341900807619517602L; private String spatial; private String subject; private Point location; private Double latitude; private Double longitude; private Long id; private Taxon taxon; private Set<Taxon> taxa = new HashSet<Taxon>(); private List<Comment> comments = new ArrayList<>(); private Set<Annotation> annotations = new HashSet<Annotation>(); /** * REMEMBER: spatial is a reserved word in mysql! * @return the location as a string */ @Column(name = "locality") @Size(max = 255) public String getSpatial() { return spatial; } public void setSpatial(final String locality) { this.spatial = locality; } @Size(max = 255) public String getSubject() { return subject; } public void setSubject(String keywords) { this.subject = keywords; } @Type(type = "spatialType") public Point getLocation() { return location; } public void setLocation(Point location) { this.location = location; } public void setId(Long newId) { this.id = newId; } @Id @GeneratedValue(generator = "table-hilo", strategy = GenerationType.TABLE) public Long getId() { return id; } public Double getLatitude() { return latitude; } public void setLatitude(Double latitude) { this.latitude = latitude; updateLocation(); } public Double getLongitude() { return longitude; } public void setLongitude(Double longitude) { this.longitude = longitude; updateLocation(); } private void updateLocation() { if(this.latitude != null && this.longitude != null) { GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null); this.location = geometryFactory.createPoint(new Coordinate(this.longitude, this.latitude)); } else { this.location = null; } } /** * @return the taxon */ @ManyToOne(fetch = FetchType.LAZY) public Taxon getTaxon() { return taxon; } /** * @param taxon the taxon to set */ public void setTaxon(Taxon taxon) { this.taxon = taxon; } /* (non-Javadoc) * @see org.emonocot.model.Multimedia#getTaxa() */ @ManyToMany(fetch = FetchType.LAZY) @JoinTable(name = "Taxon_Image", joinColumns = {@JoinColumn(name = "images_id")}, inverseJoinColumns = {@JoinColumn(name = "Taxon_id")}) @Cascade({ CascadeType.SAVE_UPDATE, CascadeType.MERGE }) @JsonSerialize(contentUsing = TaxonSerializer.class) public Set<Taxon> getTaxa() { return taxa; } /* (non-Javadoc) * @see org.emonocot.model.Multimedia#setTaxa(java.util.Set) */ @Override @JsonDeserialize(contentUsing = TaxonDeserializer.class) public void setTaxa(Set<Taxon> taxa) { this.taxa = taxa; } /* (non-Javadoc) * @see org.emonocot.model.Multimedia#getAnnotations() */ @Override @OneToMany(fetch = FetchType.LAZY, orphanRemoval = true) @JoinColumn(name = "annotatedObjId") @Where(clause = "annotatedObjType = 'Image'") @Cascade({ CascadeType.SAVE_UPDATE, CascadeType.MERGE, CascadeType.DELETE }) @JsonIgnore public Set<Annotation> getAnnotations() { return annotations; } /* (non-Javadoc) * @see org.emonocot.model.Multimedia#setAnnotations(java.util.Set) */ @Override public void setAnnotations(Set<Annotation> annotations) { this.annotations = annotations; } /* (non-Javadoc) * @see org.emonocot.model.Multimedia#getComments() */ @OneToMany(fetch = FetchType.LAZY, orphanRemoval = true) @JoinColumn(name = "commentPage_id") @OrderBy("created DESC") @Where(clause = "commentPage_type = 'Image'") @Cascade({ CascadeType.SAVE_UPDATE, CascadeType.MERGE, CascadeType.DELETE }) @JsonIgnore public List<Comment> getComments() { return comments; } /** * @param comments - Comments made about this image */ @JsonIgnore public void setComments(List<Comment> comments) { this.comments = comments; } /* (non-Javadoc) * @see org.emonocot.model.Multimedia#getType() */ @Override @Transient public MediaType getType() { return MediaType.StillImage; } @Override public SolrInputDocument toSolrInputDocument() { SolrInputDocument sid = super.toSolrInputDocument(); StringBuilder summary = new StringBuilder().append(getAudience()) .append(" ").append(getCreator()).append(" ") .append(getDescription()).append(" ").append(getPublisher()) .append(" ").append(getReferences()).append(" ") .append(getSpatial()).append(" ").append(getSubject()) .append(" ").append(getTitle()).append(" "); if(getTaxon() != null) { addField(sid,"taxon.family_ss", getTaxon().getFamily()); addField(sid,"taxon.genus_ss", getTaxon().getGenus()); addField(sid,"taxon.order_s", getTaxon().getOrder()); addField(sid,"taxon.subfamily_ss", getTaxon().getSubfamily()); addField(sid,"taxon.subgenus_s", getTaxon().getSubgenus()); addField(sid,"taxon.subtribe_ss", getTaxon().getSubtribe()); addField(sid,"taxon.tribe_ss", getTaxon().getTribe()); summary.append(" ").append(getTaxon().getClazz()) .append(" ").append(getTaxon().getClazz()) .append(" ").append(getTaxon().getFamily()) .append(" ").append(getTaxon().getGenus()) .append(" ").append(getTaxon().getKingdom()) .append(" ").append(getTaxon().getOrder()) .append(" ").append(getTaxon().getPhylum()) .append(" ").append(getTaxon().getSubfamily()) .append(" ").append(getTaxon().getSubgenus()) .append(" ").append(getTaxon().getSubtribe()) .append(" ").append(getTaxon().getTribe()); } sid.addField("searchable.solrsummary_t", summary); if (getLocation() != null) { try { WKTWriter wktWriter = new WKTWriter(); sid.addField("geo", wktWriter.write(getLocation())); } catch (Exception e) { logger.error(e.getLocalizedMessage()); } } return sid; } @Override public String toString() { StringBuffer stringBuffer = new StringBuffer(); stringBuffer.append(identifier); if(getTitle() != null) { stringBuffer.append(": \"" + getTitle() + "\""); } return stringBuffer.toString(); } }