Repository: olingo-odata2 Updated Branches: refs/heads/master cceffb310 -> 2d07b9fa9
[OLINGO-1095] Check for embedded attributes Project: http://git-wip-us.apache.org/repos/asf/olingo-odata2/repo Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata2/commit/2d07b9fa Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/2d07b9fa Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/2d07b9fa Branch: refs/heads/master Commit: 2d07b9fa98eb970a9554ca13a6492a568d79a1b0 Parents: cceffb3 Author: mibo <[email protected]> Authored: Sat Mar 25 08:42:15 2017 +0100 Committer: mibo <[email protected]> Committed: Sat Mar 25 08:42:15 2017 +0100 ---------------------------------------------------------------------- .../core/access/data/JPAQueryBuilder.java | 71 ++++++++++++++------ 1 file changed, 51 insertions(+), 20 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/2d07b9fa/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAQueryBuilder.java ---------------------------------------------------------------------- diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAQueryBuilder.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAQueryBuilder.java index bf20832..6852a17 100644 --- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAQueryBuilder.java +++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAQueryBuilder.java @@ -18,14 +18,6 @@ ******************************************************************************/ package org.apache.olingo.odata2.jpa.processor.core.access.data; -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.persistence.EntityManager; -import javax.persistence.Query; - import org.apache.olingo.odata2.api.edm.EdmException; import org.apache.olingo.odata2.api.uri.UriInfo; import org.apache.olingo.odata2.api.uri.info.DeleteUriInfo; @@ -44,6 +36,16 @@ import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLContextType; import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLStatement; import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmMapping; +import javax.persistence.EntityManager; +import javax.persistence.Query; +import javax.persistence.metamodel.Attribute; +import javax.persistence.metamodel.EntityType; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + public class JPAQueryBuilder { enum UriInfoType { @@ -177,7 +179,7 @@ public class JPAQueryBuilder { JPQLContext jpqlContext = buildJPQLContext(contextType, uriParserResultView); JPQLStatement jpqlStatement = JPQLStatement.createBuilder(jpqlContext).build(); - return em.createQuery(normalizeMembers(jpqlStatement.toString())); + return em.createQuery(normalizeMembers(em, jpqlStatement.toString())); } @@ -195,24 +197,19 @@ public class JPAQueryBuilder { public ODataJPATombstoneEntityListener getODataJPATombstoneEntityListener(UriInfo uriParserResultView) throws InstantiationException, IllegalAccessException, EdmException { JPAEdmMapping mapping = (JPAEdmMapping) uriParserResultView.getTargetEntitySet().getEntityType().getMapping(); - ODataJPATombstoneEntityListener listener = null; if (mapping.getODataJPATombstoneEntityListener() != null) { - listener = (ODataJPATombstoneEntityListener) mapping.getODataJPATombstoneEntityListener().newInstance(); + return (ODataJPATombstoneEntityListener) mapping.getODataJPATombstoneEntityListener().newInstance(); } - return listener; + return null; } public JPQLContext buildJPQLContext(JPQLContextType contextType, UriInfo uriParserResultView) throws ODataJPAModelException, ODataJPARuntimeException { - JPQLContext jpqlContext = null; if (pageSize > 0 && (contextType == JPQLContextType.SELECT || contextType == JPQLContextType.JOIN)) { - jpqlContext = JPQLContext.createBuilder(contextType, - uriParserResultView, true).build(); + return JPQLContext.createBuilder(contextType, uriParserResultView, true).build(); } else { - jpqlContext = JPQLContext.createBuilder(contextType, - uriParserResultView).build(); + return JPQLContext.createBuilder(contextType, uriParserResultView).build(); } - return jpqlContext; } public JPQLContextType determineJPQLContextType(UriInfo uriParserResultView, UriInfoType type) { @@ -240,10 +237,10 @@ public class JPAQueryBuilder { return contextType; } - private static final Pattern NORMALIZATION_NEEDED_PATTERN = Pattern.compile(".*[\\s\\(](\\S+\\.\\S+\\.\\S+).*"); + private static final Pattern NORMALIZATION_NEEDED_PATTERN = Pattern.compile(".*[\\s(](\\S+\\.\\S+\\.\\S+).*"); private static final Pattern JOIN_ALIAS_PATTERN = Pattern.compile(".*\\sJOIN\\s(\\S*\\s\\S*).*"); - private static String normalizeMembers(String jpqlQuery) { + private static String normalizeMembers(EntityManager em, String jpqlQuery) { // check if normalization is needed (if query contains "x.y.z" elements // starting with space or parenthesis) Matcher normalizationNeededMatcher = NORMALIZATION_NEEDED_PATTERN.matcher(jpqlQuery); @@ -251,6 +248,10 @@ public class JPAQueryBuilder { return jpqlQuery; } + if (containsEmbeddedAttributes(em, jpqlQuery)) { + return jpqlQuery; + } + String normalizedJpqlQuery = jpqlQuery; Map<String, String> joinAliases = new HashMap<String, String>(); @@ -306,6 +307,36 @@ public class JPAQueryBuilder { JPQLStatement.KEYWORD.SELECT_DISTINCT + JPQLStatement.DELIMITER.SPACE); } + /** + * Verify via {@link EntityManager} if one of the attributes of the selected entity + * contains a embedded attribute. + * Return true if at least one embedded attribute is found or false if non embedded + * attribute is found. + * + * @param em according entity manager + * @param jpqlQuery query to verify + * @return true if at least one embedded attribute is found or false if non embedded + * attribute is found. + */ + private static boolean containsEmbeddedAttributes(EntityManager em, String jpqlQuery) { + Set<EntityType<?>> types = em.getMetamodel().getEntities(); + int pos = jpqlQuery.indexOf("FROM ") + 5; + int lastpos = jpqlQuery.indexOf(" ", pos); + final String queriedEntity = jpqlQuery.substring(pos, lastpos); + for (EntityType<?> type : types) { + if(queriedEntity.equals(type.getName())) { + Set<Attribute<?, ?>> attributes = (Set<Attribute<?, ?>>) type.getAttributes(); + for (Attribute<?, ?> attribute : attributes) { + if(jpqlQuery.contains(attribute.getName()) && + attribute.getPersistentAttributeType() == Attribute.PersistentAttributeType.EMBEDDED) { + return true; + } + } + } + } + return false; + } + private static int ordinalIndexOf(String str, char s, int n) { int pos = str.indexOf(s, 0); while (n-- > 0 && pos != -1) {
