Java tutorial
/* * polymap.org * Copyright 2011, Falko Brutigam, and other contributors as indicated * by the @authors tag. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software 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 * Lesser General Public License for more details. */ package org.polymap.biotop.model; import java.util.Calendar; import java.util.Date; import java.util.Locale; import org.geotools.data.DefaultQuery; import org.geotools.data.Query; import org.geotools.feature.NameImpl; import org.geotools.feature.simple.SimpleFeatureBuilder; import org.geotools.feature.simple.SimpleFeatureTypeBuilder; import org.geotools.filter.visitor.DuplicatingFilterVisitor; import org.opengis.feature.Feature; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.feature.type.FeatureType; import org.opengis.filter.Filter; import org.opengis.filter.FilterFactory2; import org.opengis.filter.PropertyIsLike; import org.opengis.filter.expression.Literal; import org.opengis.filter.expression.PropertyName; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.qi4j.api.value.ValueBuilder; import com.google.common.base.Joiner; import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.MultiPolygon; import com.vividsolutions.jts.geom.Polygon; import org.polymap.core.data.util.Geometries; import org.polymap.core.model.Entity; import org.polymap.core.model.EntityType; import org.polymap.core.model.EntityType.Property; import org.polymap.core.qi4j.QiModule; import org.polymap.core.qi4j.QiModule.EntityCreator; import org.polymap.core.runtime.Polymap; import org.polymap.rhei.data.entityfeature.DefaultEntityProvider; import org.polymap.rhei.data.entityfeature.EntityProvider2; import org.polymap.biotop.model.constant.Erhaltungszustand; import org.polymap.biotop.model.constant.Pflegezustand; import org.polymap.biotop.model.constant.Schutzstatus; import org.polymap.biotop.model.constant.Status; /** * * * @author <a href="http://www.polymap.de">Falko Brutigam</a> */ public class BiotopEntityProvider extends DefaultEntityProvider<BiotopComposite> implements EntityProvider2<BiotopComposite> { private static Log log = LogFactory.getLog(BiotopEntityProvider.class); /** * The properties (name/type) of the feature type provided. */ public enum PROP { Biotopnummer(String.class, "objnr", true), SBK(String.class, null, false, "SBK/TK25/UNr."), Name( String.class, "name", true), Biotoptyp(String.class, null, false), BiotoptypNr(String.class, "biotoptypNr", false), BiotoptypCode(String.class, "biotoptypCode", false), BiotoptypVwv( String.class, null, false, "VwV"), Geprueft(Boolean.class, "geprueft", true, "Geprft"), Schutzstatus( String.class, null, false), Status(String.class, "status", true), LKNr(String.class, "objnr_landkreise", true, "LK-Nr"), Erhaltungszustand(String.class, null, false), ErhaltungszustandCode(String.class, null, false), Bekanntmachung(Date.class, null, false), ErfasstAm(Date.class, null, false), ErfasstVon(String.class, null, false), BearbeitetAm( Date.class, null, false), BearbeitetVon( String.class, null, false), Gesamtflaeche( Double.class, "flaeche", false), Pflegezustand( String.class, null, true), Pflegebedarf( Boolean.class, "pflegeBedarf", true); public static PROP forName(String name) { for (PROP prop : PROP.values()) { if (prop.name.equals(name)) { return prop; } } return null; } /** The Feature property type. */ Class type; /** The Feature property name. */ String name = name(); // The Entity property name. */ String mappedName = name(); /* */ boolean searchable = true; PROP(Class type, String mapped, boolean searchable) { this.type = type; this.mappedName = mapped; this.searchable = searchable; } PROP(Class type, String mapped, boolean searchable, String name) { this(type, mapped, searchable); this.name = name; } public <T> T cast(Object value) { return (T) type.cast(value); } public String toString() { return name; } } public BiotopEntityProvider(QiModule repo) { super(repo, BiotopComposite.class, new NameImpl(BiotopRepository.NAMESPACE, "Biotop")); } public BiotopComposite newEntity(final EntityCreator<BiotopComposite> creator) throws Exception { return ((BiotopRepository) repo).newBiotop(creator); } public FeatureType buildFeatureType() { EntityType entityType = getEntityType(); SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder(); builder.setName(getEntityName()); CoordinateReferenceSystem crs = getCoordinateReferenceSystem(getDefaultGeometry()); builder.add(getDefaultGeometry(), MultiPolygon.class, crs); builder.setDefaultGeometry(getDefaultGeometry()); for (PROP prop : PROP.values()) { builder.add(prop.name, prop.type); } return builder.buildFeatureType(); } @Override public Query transformQuery(Query query) { Filter filter = query.getFilter(); Filter dublicate = filter == null ? null : (Filter) filter.accept(new DuplicatingFilterVisitor() { // property name @Override public Object visit(PropertyName input, Object data) { PROP prop = PROP.forName(input.getPropertyName()); if (prop != null) { if (!prop.searchable) { // MessageDialog.openInformation( PolymapWorkbench.getShellToParentOn(), // "Achtung", "Das Feld '" + prop.name + "' kann im Standardfilter nicht durchsucht werden.\nBenutzen Sie stattdessen den Filter 'Naturschutz'." ); // return Filter.EXCLUDE; throw new RuntimeException("Das Feld '" + prop.name + "' kann im Standardfilter nicht durchsucht werden. Benutzen Sie stattdessen den Filter 'Naturschutz'."); } else { return getFactory(data).property(prop.mappedName); } } else { log.info("No such prop: " + input.getPropertyName()); return input; } } // literal: status -> id @Override public Object visit(Literal literal, Object data) { Object value = literal.getValue(); if (value instanceof String) { Status status = Status.all.forLabelOrSynonym((String) value); if (status != null) { return getFactory(data).literal(status.id); } } return literal; } // StandardFilterProvider does isLike for all Strings @Override public Object visit(PropertyIsLike isLike, Object data) { PropertyName propName = (PropertyName) visit((PropertyName) isLike.getExpression(), data); if (propName.getPropertyName().equals(PROP.Status.mappedName)) { FilterFactory2 ff2 = getFactory(data); return ff2.equals(propName, ff2.literal(Status.all.forLabelOrSynonym(isLike.getLiteral()).id)); } else { return super.visit(isLike, data); } } }, null); // XXX change requested properties DefaultQuery result = new DefaultQuery(query); result.setFilter(dublicate); return result; } @Override public Feature buildFeature(Entity entity, FeatureType schema) { SimpleFeatureBuilder fb = new SimpleFeatureBuilder((SimpleFeatureType) schema); BiotopComposite biotop = (BiotopComposite) entity; try { fb.set(getDefaultGeometry(), biotop.geom().get()); EntityType<BiotopComposite> entityType = getEntityType(); for (PROP prop : PROP.values()) { if (prop.mappedName != null) { Property entityProp = entityType.getProperty(prop.mappedName); if (entityProp != null) { Object value = entityProp.getValue(biotop); fb.set(prop.name, entityProp.getValue(biotop)); } } } fb.set(PROP.SBK.name, Joiner.on("/").useForNull("-").join(biotop.objnr_sbk().get(), biotop.tk25().get(), biotop.unr().get())); String nummer = biotop.biotoptyp2ArtNr().get(); BiotoptypArtComposite2 biotoptyp = ((BiotopRepository) repo).btForNummer(nummer); fb.set(PROP.Biotoptyp.name, biotoptyp != null ? biotoptyp.bezeichnung().get() : null); fb.set(PROP.BiotoptypNr.name, biotoptyp != null ? biotoptyp.nummer_2012().get() : null); fb.set(PROP.BiotoptypCode.name, biotoptyp != null ? biotoptyp.code().get() : null); fb.set(PROP.BiotoptypVwv.name, biotoptyp != null ? biotoptyp.vwv().get() : null); Schutzstatus schutzstatus = Schutzstatus.all.forId(biotop.schutzstatus().get()); fb.set(PROP.Schutzstatus.name, schutzstatus != null ? schutzstatus.label : null); Status status = Status.all.forId(biotop.status().get()); fb.set(PROP.Status.name, status != null ? status.label : null); Erhaltungszustand erhaltungszustand = Erhaltungszustand.all.forId(biotop.erhaltungszustand().get()); fb.set(PROP.Erhaltungszustand.name, erhaltungszustand != null ? erhaltungszustand.label : null); fb.set(PROP.ErhaltungszustandCode.name, erhaltungszustand != null ? (erhaltungszustand.id == 0 ? "kA" : erhaltungszustand.id) : null); Pflegezustand pflegezustand = Pflegezustand.all.forId(biotop.pflegeZustand().get()); fb.set(PROP.Pflegezustand.name, pflegezustand != null ? pflegezustand.label : null); AktivitaetValue aktivitaet = biotop.bearbeitung().get(); if (aktivitaet != null) { fb.set(PROP.BearbeitetAm.name, aktivitaet.wann().get()); fb.set(PROP.BearbeitetVon.name, aktivitaet.wer().get()); } aktivitaet = biotop.erfassung().get(); if (aktivitaet != null) { fb.set(PROP.ErfasstAm.name, aktivitaet.wann().get()); fb.set(PROP.ErfasstVon.name, aktivitaet.wer().get()); } aktivitaet = biotop.bekanntmachung().get(); if (aktivitaet != null) { fb.set(PROP.Bekanntmachung.name, aktivitaet.wann().get()); } } catch (Exception e) { log.warn("", e); } return fb.buildFeature(biotop.id()); } @Override public void modifyFeature(Entity entity, String propName, Object value) throws Exception { BiotopComposite biotop = (BiotopComposite) entity; if (propName.equals(getDefaultGeometry())) { if (value instanceof MultiPolygon) { biotop.geom().set((MultiPolygon) value); } // geometry buffer op results in Polygon (instead of MultiPolygon) // see #72: http://polymap.org/biotop/ticket/72 else if (value instanceof Polygon) { MultiPolygon geom = new GeometryFactory().createMultiPolygon(new Polygon[] { (Polygon) value }); biotop.geom().set(geom); } else { throw new IllegalStateException("Falscher Geometrietyp: " + value.getClass().getSimpleName()); } ValueBuilder<AktivitaetValue> builder = repo.newValueBuilder(AktivitaetValue.class); AktivitaetValue prototype = builder.prototype(); Calendar now = Calendar.getInstance(Locale.GERMANY); now.set(Calendar.MILLISECOND, 0); prototype.wann().set(now.getTime()); prototype.wer().set(Polymap.instance().getUser().getName()); prototype.bemerkung().set("nderung der Geometrie"); biotop.bearbeitung().set(builder.newInstance()); } else if (propName.equals(PROP.Name.toString())) { biotop.name().set((String) value); } // else if (propName.equals( PROP.Biotoptyp.toString() )) { // biotop.biotoptypArtNr().set( (String)value ); // } else if (propName.equals(PROP.Geprueft.toString())) { biotop.geprueft().set("ja".equals(value)); } else if (propName.equals(PROP.Status.toString()) && value != null) { Status status = Status.all.forLabelOrSynonym((String) value); if (status != null) { biotop.status().set(status.id); } } else if (propName.equals(PROP.LKNr.toString())) { biotop.objnr_landkreise().set((String) value); } // else { // throw new RuntimeException( "Unhandled property: " + propName ); // } } public CoordinateReferenceSystem getCoordinateReferenceSystem(String propName) { try { return Geometries.crs("EPSG:31468"); } catch (Exception e) { throw new RuntimeException(e); } } public String getDefaultGeometry() { return "geom"; } }