Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add feature hierarchy feature #245

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
48112cf
update api version to next snapshot
May 29, 2020
8875b2e
update to changes in HerarchicalParameterOutput
May 29, 2020
58c1c84
implement creation of hierarchical features
May 29, 2020
be80dc7
add getLevel
May 29, 2020
1d21550
Merge branch 'develop' into feature/feature_hierarchy
May 29, 2020
0fcaa68
formatting
Jun 3, 2020
20f4d1f
change to collection instead of set in parsToIds
Jun 3, 2020
8ece5c1
add reverse processing of result if filter parameter are used, e.g. p…
Jun 3, 2020
e38b2d7
Support full hierarchy query without "level" parameter and support qu…
Jun 3, 2020
3b5c452
exctract hibernate files from jar because the jar file was locked whe…
Jun 4, 2020
233908a
Add filter in logback to no log hibernate criteria warnings
Jun 4, 2020
cf8d50f
Merge branch 'develop' into feature/feature_hierarchy
Jun 19, 2020
616b5a5
Merge branch 'develop' into feature/feature_hierarchy
Jun 26, 2020
b608c6d
Merge branch 'develop' into feature/feature_hierarchy
Jul 14, 2020
ac21a93
Add parents and children only if available
Jul 14, 2020
8e625c6
Add HierarchicalDao to reuse the hierachical querying in multiple dao…
Jul 14, 2020
47cfd45
Add check for hierarchical query parameters and add the children
Jul 14, 2020
afe8e97
Merge branch 'develop' into feature/feature_hierarchy
Jul 14, 2020
2dfdd64
Decrease jts version to 1.16.1 because of Binary-Incompatible-Change …
Jul 14, 2020
60e46ce
move level check for query parameters to abstract dao to use in all daos
Jul 14, 2020
d42e00e
Merge branch 'develop' into feature/feature_hierarchy
Jul 20, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions NOTICE
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ This project includes:
Checker Qual under The MIT License
ClassMate under Apache License, Version 2.0
Commons Lang under The Apache Software License, Version 2.0
commons-compiler under New BSD License
Cross-Origin Resource Sharing (CORS) Filter under The Apache Software License, Version 2.0
dom4j under BSD 3-clause New License
ehcache under The Apache Software License, Version 2.0
Expand All @@ -52,6 +53,7 @@ This project includes:
jackson-databind under The Apache Software License, Version 2.0
Jakarta Activation under EDL 1.0
Jakarta XML Binding API under Eclipse Distribution License - v 1.0
janino under New BSD License
Java Annotation Indexer under Apache License, Version 2.0
Java Property Utility under The Apache Software License, Version 2.0
Java Transaction API under Common Development and Distribution License or GNU General Public License, Version 2 with the Classpath Exception
Expand Down Expand Up @@ -101,7 +103,7 @@ This project includes:
org.apache.xmlgraphics:batik-transcoder under The Apache Software License, Version 2.0
org.apache.xmlgraphics:batik-util under The Apache Software License, Version 2.0
org.apache.xmlgraphics:batik-xml under The Apache Software License, Version 2.0
org.locationtech.jts:jts-core under Eclipse Public License, Version 2.0 or Eclipse Distribution License - v 1.0
org.locationtech.jts:jts-core under Eclipse Publish License, Version 1.0 or Eclipse Distribution License - v 1.0
PostGIS Geometry under GNU Lesser General Public License
Postgis JDBC Driver under GNU Lesser General Public License
PostgreSQL JDBC Driver under BSD-2-Clause
Expand All @@ -112,7 +114,6 @@ This project includes:
Sensor Web Server DAO Impl - Webapp under GNU General Public License, Version 2.0
Sensor Web Server Database Model - Entities under The Apache Software License, Version 2.0
Sensor Web Server Database Model - Hibernate Types under The Apache Software License, Version 2.0
Sensor Web Server Database Model - Mappings under The Apache Software License, Version 2.0
Sensor Web Server Helgoland - IO module under GNU General Public License, Version 2.0
Sensor Web Server Helgoland - PDF report structure under GNU General Public License, Version 2.0
Sensor Web Server Helgoland - REST module under GNU General Public License, Version 2.0
Expand Down
52 changes: 47 additions & 5 deletions dao/src/main/java/org/n52/series/db/da/FeatureRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,17 @@
*/
package org.n52.series.db.da;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.hibernate.Session;
import org.n52.io.request.IoParameters;
import org.n52.io.request.Parameters;
import org.n52.io.response.AbstractOutput;
import org.n52.io.response.FeatureOutput;
import org.n52.io.response.HierarchicalParameterOutput;
import org.n52.io.response.ServiceOutput;
import org.n52.io.response.dataset.DatasetParameters;
import org.n52.io.response.dataset.StationOutput;
Expand Down Expand Up @@ -75,18 +80,55 @@ protected FeatureOutput createCondensed(FeatureEntity entity, DbQuery query, Ses

@Override
protected FeatureOutput createExpanded(FeatureEntity entity, DbQuery query, Session session) {
return createExpanded(entity, query, false, false, query.getLevel(), session);
}

protected FeatureOutput createExpanded(FeatureEntity entity, DbQuery query, boolean isParent, boolean isChild,
Integer level, Session session) {
FeatureOutput result = createCondensed(entity, query, session);
ServiceOutput service = (query.getHrefBase() != null)
? getCondensedExtendedService(getServiceEntity(entity), query.withoutFieldsFilter())
: getCondensedService(getServiceEntity(entity), query.withoutFieldsFilter());
result.setValue(AbstractOutput.SERVICE, service, query.getParameters(), result::setService);
if (!isParent && !isChild) {
Class<DatasetEntity> clazz = DatasetEntity.class;
DatasetDao<DatasetEntity> seriesDao = new DatasetDao<>(session, clazz);
List<DatasetEntity> series = seriesDao.getInstancesWith(entity, query);
Map<String, DatasetParameters> timeseriesList = createTimeseriesList(series, query);
result.setValue(StationOutput.PROPERTIES, timeseriesList, query.getParameters(), result::setDatasets);
}
if (!isParent && !isChild && entity.hasParents()) {
List<FeatureOutput> parents = getMemberList(entity.getParents(), query, level, true, false, session);
result.setValue(HierarchicalParameterOutput.PARENTS, parents, query.getParameters(), result::setParents);
}
if (level != null && level > 0) {
if (((!isParent && !isChild) || (!isParent && isChild)) && entity.hasChildren()) {
List<FeatureOutput> children =
getMemberList(entity.getChildren(), query, level - 1, false, true, session);
result.setValue(HierarchicalParameterOutput.CHILDREN, children, query.getParameters(),
result::setChildren);
}

Class<DatasetEntity> clazz = DatasetEntity.class;
DatasetDao<DatasetEntity> seriesDao = new DatasetDao<>(session, clazz);
List<DatasetEntity> series = seriesDao.getInstancesWith(entity, query);
Map<String, DatasetParameters> timeseriesList = createTimeseriesList(series, query);
result.setValue(StationOutput.PROPERTIES, timeseriesList, query.getParameters(), result::setDatasets);
}
return result;
}

private List<FeatureOutput> getMemberList(Set<FeatureEntity> entities, DbQuery query, Integer level,
boolean isNotParent, boolean isNotChild, Session session) {
List<FeatureOutput> list = new LinkedList<>();
for (FeatureEntity e : entities) {
list.add(createExpanded(e, query, isNotParent, isNotChild, level, session));
}
return list;
}

private boolean hasFilterParameter(DbQuery query) {
IoParameters parameters = query.getParameters();
return parameters.containsParameter(Parameters.DATASETS) || parameters.containsParameter(Parameters.CATEGORIES)
|| parameters.containsParameter(Parameters.OFFERINGS)
|| parameters.containsParameter(Parameters.PHENOMENA)
|| parameters.containsParameter(Parameters.PLATFORMS)
|| parameters.containsParameter(Parameters.PROCEDURES);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
Expand Down Expand Up @@ -61,7 +62,7 @@ protected List<O> createExpanded(Collection<E> entities, DbQuery query, Session
@Override
protected List<O> createCondensed(Collection<E> entities, DbQuery query, Session session) {
return entities == null
? new ArrayList<>()
? Collections.emptyList()
: entities.stream()
.map(entity -> createCondensed(entity, query, session))
.collect(Collectors.toList());
Expand Down
27 changes: 10 additions & 17 deletions dao/src/main/java/org/n52/series/db/da/ProcedureRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,9 @@
*/
package org.n52.series.db.da;

import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.hibernate.Session;
import org.n52.io.response.AbstractOutput;
import org.n52.io.response.HierarchicalParameterOutput;
import org.n52.io.response.ProcedureOutput;
import org.n52.io.response.ServiceOutput;
import org.n52.series.db.beans.ProcedureEntity;
Expand Down Expand Up @@ -73,19 +69,16 @@ protected ProcedureOutput createExpanded(ProcedureEntity entity, DbQuery query,
? getCondensedExtendedService(getServiceEntity(entity), query.withoutFieldsFilter())
: getCondensedService(getServiceEntity(entity), query.withoutFieldsFilter());
result.setValue(AbstractOutput.SERVICE, service, query.getParameters(), result::setService);
result.setParents(createCondensed(entity.getParents(), query, session));
result.setChildren(createCondensed(entity.getChildren(), query, session));
return result;
}

protected List<ProcedureOutput> createCondensedHierarchyMembers(Set<ProcedureEntity> members,
DbQuery parameters,
Session session) {
return members == null
? Collections.emptyList()
: members.stream()
.map(e -> createCondensed(e, parameters, session))
.collect(Collectors.toList());
if (entity.hasParents()) {
result.setValue(HierarchicalParameterOutput.PARENTS, createCondensed(entity.getParents(), query, session),
query.getParameters(), result::setParents);
}
if (entity.hasChildren()) {
result.setValue(HierarchicalParameterOutput.CHILDREN,
createCondensed(entity.getChildren(), query, session), query.getParameters(), result::setChildren);
}
return result;
}

}
26 changes: 26 additions & 0 deletions dao/src/main/java/org/n52/series/db/dao/AbstractDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.geolatte.geom.GeometryType;
import org.hibernate.Criteria;
Expand All @@ -53,6 +55,7 @@
import org.hibernate.transform.RootEntityResultTransformer;
import org.n52.io.request.FilterResolver;
import org.n52.io.request.IoParameters;
import org.n52.io.request.Parameters;
import org.n52.series.db.DataAccessException;
import org.n52.series.db.DataModelUtil;
import org.n52.series.db.beans.DatasetEntity;
Expand Down Expand Up @@ -337,6 +340,29 @@ private GeometryType getGeometryType(String geometryType) {
.findAny().orElse(null);
}

protected DbQuery checkLevelParameterForHierarchyQuery(DbQuery query) {
IoParameters params = null;
if (query.getLevel() != null) {
if (query.getParameters().containsParameter(Parameters.FEATURES) && !(this instanceof FeatureDao)) {
Collection<Long> ids = new FeatureDao(session).getChildrenIds(query);
if (ids != null && !ids.isEmpty()) {
params = query.getParameters().extendWith(Parameters.FEATURES, toStringList(ids));
}
} else if (query.getParameters().containsParameter(Parameters.PROCEDURES)
&& !(this instanceof ProcedureDao)) {
Collection<Long> ids = new ProcedureDao(session).getChildrenIds(query);
if (ids != null && !ids.isEmpty()) {
params = query.getParameters().extendWith(Parameters.PROCEDURES, toStringList(ids));
}
}
}
return params != null ? new DbQuery(params) : query;
}

protected List<String> toStringList(Collection<Long> set) {
return set.stream().map(s -> s.toString()).collect(Collectors.toList());
}

/**
* Translate the {@link Criteria criteria} to SQL.
*
Expand Down
16 changes: 9 additions & 7 deletions dao/src/main/java/org/n52/series/db/dao/DataDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,18 +88,19 @@ public T getInstance(Long key, DbQuery parameters) throws DataAccessException {
/**
* Retrieves all available observation instances.
*
* @param parameters query parameters.
* @param q query parameters.
*
* @return all instances matching the given query parameters.
*
* @throws DataAccessException if accessing database fails.
*/
@Override
@SuppressWarnings("unchecked")
public List<T> getAllInstances(DbQuery parameters) throws DataAccessException {
LOGGER.debug("get all instances: {}", parameters);
Criteria criteria = getDefaultCriteria(parameters);
parameters.addTimespanTo(criteria);
public List<T> getAllInstances(DbQuery q) throws DataAccessException {
DbQuery query = checkLevelParameterForHierarchyQuery(q);
LOGGER.debug("get all instances: {}", query);
Criteria criteria = getDefaultCriteria(query);
query.addTimespanTo(criteria);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(toSQLString(criteria));
}
Expand All @@ -111,14 +112,15 @@ public List<T> getAllInstances(DbQuery parameters) throws DataAccessException {
*
* @param dataset
* the dataset the observations belongs to.
* @param query
* @param q
* some query parameters to restrict result.
* @return all observation entities belonging to the given series which match the given query.
* @throws DataAccessException
* if accessing database fails.
*/
@SuppressWarnings("unchecked")
public List<T> getAllInstancesFor(Long dataset, DbQuery query) throws DataAccessException {
public List<T> getAllInstancesFor(Long dataset, DbQuery q) throws DataAccessException {
DbQuery query = checkLevelParameterForHierarchyQuery(q);
LOGGER.debug("get all instances for series '{}': {}", dataset, query);
Criteria criteria = getDefaultCriteria(query);
criteria.createCriteria(DataEntity.PROPERTY_DATASET).add(Restrictions.eq(DatasetEntity.PROPERTY_ID, dataset));
Expand Down
6 changes: 4 additions & 2 deletions dao/src/main/java/org/n52/series/db/dao/DatasetDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ public DatasetDao(Session session, Class<T> clazz) {

@Override
@SuppressWarnings("unchecked")
public List<T> find(DbQuery query) {
public List<T> find(DbQuery q) {
DbQuery query = checkLevelParameterForHierarchyQuery(q);
LOGGER.debug("find entities: {}", query);

String searchTerm = "%" + query.getSearchTerm() + "%";
Expand Down Expand Up @@ -121,7 +122,8 @@ protected T getInstance(String key, DbQuery query, Class<T> clazz) {

@Override
@SuppressWarnings("unchecked")
public List<T> getAllInstances(DbQuery query) throws DataAccessException {
public List<T> getAllInstances(DbQuery q) throws DataAccessException {
DbQuery query = checkLevelParameterForHierarchyQuery(q);
LOGGER.debug("get all instances: {}", query);
Criteria criteria = query.addFilters(getDefaultCriteria(query), getDatasetProperty());
if (LOGGER.isDebugEnabled()) {
Expand Down
18 changes: 4 additions & 14 deletions dao/src/main/java/org/n52/series/db/dao/DbQuery.java
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@ public Interval getTimespan() {
.toInterval();
}

public Integer getLevel() {
return parameters.getLevel();
}

public Envelope getSpatialFilter() {
BoundingBox spatialFilter = parameters.getSpatialFilter();
if (spatialFilter != null) {
Expand Down Expand Up @@ -401,20 +405,6 @@ private boolean hasValues(Set<String> values) {
return values != null && !values.isEmpty();
}

// private Set<String> getStationaryIds(Set<String> platforms) {
// return platforms.stream()
// .filter(PlatformType::isStationaryId)
// .map(PlatformType::extractId)
// .collect(toSet());
// }
//
// private Set<String> getMobileIds(Set<String> platforms) {
// return platforms.stream()
// .filter(PlatformType::isMobileId)
// .map(PlatformType::extractId)
// .collect(toSet());
// }

public Criteria addResultTimeFilter(Criteria criteria) {
if (parameters.shallClassifyByResultTimes()) {
criteria.add(parameters.getResultTimes().stream()
Expand Down
41 changes: 26 additions & 15 deletions dao/src/main/java/org/n52/series/db/dao/FeatureDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,21 @@
package org.n52.series.db.dao;

import java.util.Collection;
import java.util.Collections;
import java.util.Set;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.Restrictions;
import org.hibernate.transform.RootEntityResultTransformer;
import org.n52.io.request.IoParameters;
import org.n52.io.request.Parameters;
import org.n52.series.db.DataAccessException;
import org.n52.series.db.beans.DatasetEntity;
import org.n52.series.db.beans.FeatureEntity;
import org.n52.series.db.beans.i18n.I18nFeatureEntity;
import org.springframework.transaction.annotation.Transactional;

@Transactional
public class FeatureDao extends ParameterDao<FeatureEntity, I18nFeatureEntity> {
public class FeatureDao extends HierarchicalDao<FeatureEntity, I18nFeatureEntity> {

public FeatureDao(Session session) {
super(session);
Expand All @@ -67,25 +66,37 @@ protected Class<I18nFeatureEntity> getI18NEntityClass() {

@Override
public Collection<FeatureEntity> get(DbQuery query) {
Criteria c = session.createCriteria(getEntityClass(), getDefaultAlias())
.setResultTransformer(RootEntityResultTransformer.INSTANCE);
return getCriteria(query).list();
}

@Override
public Set<Long> getChildrenIds(DbQuery query) {
Set<String> features = query.getParameters().getFeatures();
if (features != null && !features.isEmpty()) {
return getChildrenIds(query, features, query.getLevel());
}
return Collections.emptySet();
}

@Override
protected Criteria getCriteria(DbQuery query) throws DataAccessException {
Criteria c = getDefaultCriteria();
IoParameters parameters = query.getParameters();
if (parameters.getFeatures() != null && !parameters.getFeatures().isEmpty()) {
c.add(query.getParameters().isMatchDomainIds() ? createDomainIdFilter(parameters.getFeatures())
: createIdFilter(parameters.getFeatures()));
}
query.addSpatialFilter(c);
return c.list();
return c;
}

private Criterion createDomainIdFilter(Set<String> filterValues) {
return filterValues.stream().map(filter -> Restrictions.ilike(FeatureEntity.PROPERTY_DOMAIN_ID, filter))
.collect(Restrictions::disjunction, Disjunction::add,
(a, b) -> b.conditions().forEach(a::add));
@Override
protected Set<String> getParameter(DbQuery query) {
return query.getParameters().getFeatures();
}

private Criterion createIdFilter(Set<String> filterValues) {
return Restrictions.in(FeatureEntity.PROPERTY_ID, QueryUtils.parseToIds(filterValues));
@Override
protected IoParameters replaceParameter(DbQuery query, Collection<String> entites) {
return query.getParameters().replaceWith(Parameters.FEATURES, entites);
}

}
Loading