Java tutorial
/* * This is part of Geomajas, a GIS framework, http://www.geomajas.org/. * * Copyright 2008-2015 Geosparc nv, http://www.geosparc.com/, Belgium. * * The program is available in open source according to the GNU Affero * General Public License. All contributions in this program are covered * by the Geomajas Contributors License Agreement. For full licensing * details, see LICENSE.txt in the project root. */ package org.geomajas.layer.hibernate; import java.io.Serializable; import java.util.Collection; import java.util.HashMap; import java.util.Map; import org.apache.commons.beanutils.ConvertUtils; import org.geomajas.configuration.AttributeInfo; import org.geomajas.configuration.VectorLayerInfo; import org.geomajas.global.ExceptionCode; import org.geomajas.global.GeomajasException; import org.geomajas.layer.LayerException; import org.geomajas.layer.entity.Entity; import org.geomajas.layer.entity.EntityAttributeService; import org.geomajas.layer.entity.EntityMapper; import org.geomajas.layer.feature.Attribute; import org.geomajas.layer.feature.FeatureModel; import org.geomajas.layer.hibernate.HibernateEntityMapper.HibernateEntity; import org.geomajas.service.GeoService; import org.hibernate.engine.SessionImplementor; import org.springframework.beans.factory.annotation.Autowired; import com.vividsolutions.jts.geom.Geometry; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; /** * <p> * FeatureModel implementation for the HibernateLayer. * </p> * <p> Values are read/written according to the Hibernate access type.</p> * * @author Jan De Moerloose * @author Pieter De Graef */ @Scope("prototype") @Component() public class HibernateFeatureModel extends HibernateLayerUtil implements FeatureModel { @Autowired private GeoService geoService; private int srid; @Autowired private EntityAttributeService entityMappingService; private EntityMapper entityMapper; // ------------------------------------------------------------------------- // Constructors: // ------------------------------------------------------------------------- @Override public void setLayerInfo(VectorLayerInfo layerInfo) throws LayerException { super.setLayerInfo(layerInfo); srid = geoService.getSridFromCrs(layerInfo.getCrs()); entityMapper = new HibernateEntityMapper(getSessionFactory()); } @Override public Attribute getAttribute(Object feature, String name) throws LayerException { try { return entityMappingService.getAttribute(feature, getFeatureInfo(), entityMapper, name); } catch (GeomajasException e) { throw new LayerException(e); } } @Override @SuppressWarnings("rawtypes") public Map<String, Attribute> getAttributes(Object feature) throws LayerException { try { Map<String, Attribute> attribs = new HashMap<String, Attribute>(); for (AttributeInfo attribute : getFeatureInfo().getAttributes()) { String name = attribute.getName(); if (!name.equals(getGeometryAttributeName())) { Attribute value = getAttribute(feature, name); attribs.put(name, value); } } return attribs; } catch (Exception e) { // NOSONAR throw new LayerException(e, ExceptionCode.HIBERNATE_ATTRIBUTE_ALL_GET_FAILED, feature); } } @Override public String getId(Object feature) throws LayerException { Entity entity = entityMapper.asEntity(feature); Object id = entity.getId(getFeatureInfo().getIdentifier().getName()); return id == null ? null : id.toString(); } @Override public Geometry getGeometry(Object feature) throws LayerException { Object obj = getAttributeRecursively(feature, getGeometryAttributeName()); if (obj == null) { return null; } else if (Geometry.class.isAssignableFrom(obj.getClass())) { Geometry geom = (Geometry) obj; return (Geometry) geom.clone(); } else { throw new LayerException(ExceptionCode.PROPERTY_IS_NOT_GEOMETRY, getGeometryAttributeName()); } } @Override @SuppressWarnings("unchecked") public void setAttributes(Object feature, Map<String, Attribute> attributes) throws LayerException { entityMappingService.setAttributes(feature, getFeatureInfo(), entityMapper, (Map) attributes); } @Override public void setGeometry(Object feature, Geometry geometry) throws LayerException { Entity entity = entityMapper.asEntity(feature); entity.setAttribute(getGeometryAttributeName(), geometry); } @Override public Object newInstance() throws LayerException { try { return getEntityMetadata().instantiate(null, (SessionImplementor) getSessionFactory().getCurrentSession()); } catch (Exception e) { // NOSONAR throw new LayerException(e, ExceptionCode.HIBERNATE_CANNOT_CREATE_POJO, getFeatureInfo().getDataSourceName()); } } @Override public Object newInstance(String id) throws LayerException { try { Serializable ser = (Serializable) ConvertUtils.convert(id, getEntityMetadata().getIdentifierType().getReturnedClass()); return getEntityMetadata().instantiate(ser, (SessionImplementor) getSessionFactory().getCurrentSession()); } catch (Exception e) { // NOSONAR throw new LayerException(e, ExceptionCode.HIBERNATE_CANNOT_CREATE_POJO, getFeatureInfo().getDataSourceName()); } } @Override public int getSrid() { return srid; } @Override public String getGeometryAttributeName() throws LayerException { return fixName(getFeatureInfo().getGeometryType().getName()); } @Override public boolean canHandle(Object feature) { try { return getEntityMetadata().getEntityName().equals(feature.getClass().getName()); } catch (HibernateLayerException e) { return false; } } // ------------------------------------------------------------------------- // Private functions: // ------------------------------------------------------------------------- private String fixName(String name) { return name.replace(HibernateLayerUtil.XPATH_SEPARATOR, HibernateLayerUtil.SEPARATOR); } /** * A recursive getAttribute method. In case a one-to-many is passed, an array will be returned. * * @param feature The feature wherein to search for the attribute * @param name The attribute's full name. (can be attr1.attr2) * @return Returns the value. In case a one-to-many is passed along the way, an array will be returned. * @throws LayerException oops */ private Object getAttributeRecursively(Object feature, String name) throws LayerException { if (feature == null) { return null; } // Split up properties: the first and the rest. String[] properties = name.split(SEPARATOR_REGEXP, 2); Object tempFeature; // If the first property is the identifier: if (properties[0].equals(getFeatureInfo().getIdentifier().getName())) { tempFeature = getId(feature); } else { Entity entity = entityMapper.asEntity(feature); HibernateEntity child = (HibernateEntity) entity.getChild(properties[0]); tempFeature = child == null ? null : child.getObject(); } // Detect if the first property is a collection (one-to-many): if (tempFeature instanceof Collection<?>) { Collection<?> features = (Collection<?>) tempFeature; Object[] values = new Object[features.size()]; int count = 0; for (Object value : features) { if (properties.length == 1) { values[count++] = value; } else { values[count++] = getAttributeRecursively(value, properties[1]); } } return values; } else { // Else first property is not a collection (one-to-many): if (properties.length == 1 || tempFeature == null) { return tempFeature; } else { return getAttributeRecursively(tempFeature, properties[1]); } } } }