diff --git a/src/main/java/org/reso/service/data/GenericEntityCollectionProcessor.java b/src/main/java/org/reso/service/data/GenericEntityCollectionProcessor.java index 6a24ef8..4148b11 100644 --- a/src/main/java/org/reso/service/data/GenericEntityCollectionProcessor.java +++ b/src/main/java/org/reso/service/data/GenericEntityCollectionProcessor.java @@ -269,20 +269,7 @@ public class GenericEntityCollectionProcessor implements EntityCollectionProcess // add the lookups from the database. while (resultSet.next()) { - String lookupKey = resultSet.getString(primaryFieldName); - Entity ent = new Entity(); - for (FieldInfo field : fields) - { - String fieldName = field.getFieldName(); - Object value = null; - if (selectLookup==null || selectLookup.containsKey(fieldName) ) - { - value = CommonDataProcessing.getFieldValueFromRow(field, resultSet); - ent.addProperty(new Property(null, fieldName,ValueType.PRIMITIVE, value)); - } - } - - ent.setId(createId(resource.getResourcesName(), lookupKey)); + Entity ent = CommonDataProcessing.getEntityFromRow(resultSet,resource,selectLookup); productList.add(ent); } @@ -296,12 +283,4 @@ public class GenericEntityCollectionProcessor implements EntityCollectionProcess return entCollection; } - private URI createId(String entitySetName, Object id) { - try { - return new URI(entitySetName + "('" + String.valueOf(id) + "')"); - } catch (URISyntaxException e) { - throw new ODataRuntimeException("Unable to create id for entity: " + entitySetName, e); - } - } - } diff --git a/src/main/java/org/reso/service/data/GenericEntityProcessor.java b/src/main/java/org/reso/service/data/GenericEntityProcessor.java index 114c51f..96e5e58 100644 --- a/src/main/java/org/reso/service/data/GenericEntityProcessor.java +++ b/src/main/java/org/reso/service/data/GenericEntityProcessor.java @@ -136,18 +136,8 @@ public class GenericEntityProcessor implements EntityProcessor // add the lookups from the database. while (resultSet.next()) { + Entity ent = CommonDataProcessing.getEntityFromRow(resultSet,resource,null); - String lookupKey = resultSet.getString(primaryFieldName); - Entity ent = new Entity(); - for (FieldInfo field : fields) - { - String fieldName = field.getFieldName(); - Object value = CommonDataProcessing.getFieldValueFromRow(field,resultSet); - - ent.addProperty(new Property(null, fieldName, ValueType.PRIMITIVE, value)); - } - - ent.setId(createId(resource.getResourcesName(), lookupKey)); product = ent; } diff --git a/src/main/java/org/reso/service/data/common/CommonDataProcessing.java b/src/main/java/org/reso/service/data/common/CommonDataProcessing.java index d3dd252..5490963 100644 --- a/src/main/java/org/reso/service/data/common/CommonDataProcessing.java +++ b/src/main/java/org/reso/service/data/common/CommonDataProcessing.java @@ -1,15 +1,24 @@ package org.reso.service.data.common; +import org.apache.olingo.commons.api.data.Entity; +import org.apache.olingo.commons.api.data.Property; +import org.apache.olingo.commons.api.data.ValueType; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; +import org.apache.olingo.commons.api.ex.ODataRuntimeException; import org.reso.service.data.GenericEntityCollectionProcessor; import org.reso.service.data.meta.FieldInfo; +import org.reso.service.data.meta.ResourceInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.net.URI; +import java.net.URISyntaxException; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; public class CommonDataProcessing { @@ -34,4 +43,41 @@ public class CommonDataProcessing return value; } + + public static Entity getEntityFromRow(ResultSet resultSet, ResourceInfo resource, HashMap selectLookup) throws SQLException + { + String primaryFieldName = resource.getPrimaryKeyName(); + ArrayList fields = resource.getFieldList(); + String lookupKey = null; + if (selectLookup!=null && selectLookup.get(primaryFieldName)!=null) + { + lookupKey = resultSet.getString(primaryFieldName); + } + Entity ent = new Entity(); + for (FieldInfo field : fields) + { + String fieldName = field.getFieldName(); + Object value = null; + if (selectLookup==null || selectLookup.containsKey(fieldName) ) + { + value = CommonDataProcessing.getFieldValueFromRow(field, resultSet); + ent.addProperty(new Property(null, fieldName, ValueType.PRIMITIVE, value)); + } + } + + if (lookupKey!=null) + { + ent.setId(createId(resource.getResourcesName(), lookupKey)); + } + + return ent; + } + + private static URI createId(String entitySetName, Object id) { + try { + return new URI(entitySetName + "('" + String.valueOf(id) + "')"); + } catch (URISyntaxException e) { + throw new ODataRuntimeException("Unable to create id for entity: " + entitySetName, e); + } + } } diff --git a/src/main/java/org/reso/service/data/meta/EnumFieldInfo.java b/src/main/java/org/reso/service/data/meta/EnumFieldInfo.java new file mode 100644 index 0000000..a45a034 --- /dev/null +++ b/src/main/java/org/reso/service/data/meta/EnumFieldInfo.java @@ -0,0 +1,118 @@ +package org.reso.service.data.meta; + + +import org.apache.olingo.commons.api.data.Entity; +import org.apache.olingo.commons.api.data.Property; +import org.apache.olingo.commons.api.edm.FullQualifiedName; +import org.reso.service.data.common.CommonDataProcessing; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.HashMap; + +import static org.reso.service.servlet.RESOservlet.resourceLookup; +import static org.reso.service.servlet.RESOservlet.getConnection; + +public class EnumFieldInfo extends FieldInfo +{ + private String lookupName; + private ArrayList values = new ArrayList<>(); + private static final Logger LOG = LoggerFactory.getLogger(EnumFieldInfo.class); + private boolean isCollection = false; + + private static String LOOKUP_COLUMN_NAME = "LookupValue"; + + public EnumFieldInfo(String fieldName, FullQualifiedName type) + { + super(fieldName, type); + } + + public void addValue(String value) + { + values.add(value); + } + + private void loadValues() + { + ResourceInfo resource = resourceLookup.get("Lookup"); + if (resource!=null) + { + Connection connect = getConnection(); + String queryString = null; + try + { + Statement statement = connect.createStatement(); + HashMap selectLookup = new HashMap<>(); + selectLookup.put(LOOKUP_COLUMN_NAME, true); + + queryString = "Select "+LOOKUP_COLUMN_NAME+" from "+resource.getTableName()+" WHERE LookupName = '"+lookupName+"'"; + LOG.debug("Query: "+queryString); + + ResultSet resultSet = statement.executeQuery(queryString); + while (resultSet.next()) + { + Entity ent = CommonDataProcessing.getEntityFromRow(resultSet, resource, selectLookup); + Property property = ent.getProperty(LOOKUP_COLUMN_NAME); + values.add( property.getValue().toString() ); + } + } + catch (Exception e) + { + LOG.info("Query: "+queryString); + LOG.error("Error in finding Lookup values for "+lookupName+": "+e.getMessage()); + } + } + } + + public ArrayList getValues() + { + if (values.size()==0) + { + loadValues(); + } + + return values; + } + + public void setLookupName(String name) { lookupName=name; } + + public FullQualifiedName getType() + { + if (values.size()==0) + { + loadValues(); + } + if (values.size()>0) + { + return new FullQualifiedName("org.reso.metadata.enums." + lookupName); + } + + LOG.info("No values for lookup: "+lookupName); + return super.getType(); + } + + + /** + * Accessor for lookupName + * @return + */ + public String getLookupName() + { + return lookupName; + } + + public boolean isCollection() + { + return isCollection; + } + + public void setCollection() + { + isCollection = true; + } + +} diff --git a/src/main/java/org/reso/service/data/meta/FieldInfo.java b/src/main/java/org/reso/service/data/meta/FieldInfo.java index 0925fa6..9ba8309 100644 --- a/src/main/java/org/reso/service/data/meta/FieldInfo.java +++ b/src/main/java/org/reso/service/data/meta/FieldInfo.java @@ -77,4 +77,10 @@ public class FieldInfo { return maxLength; } + + + public boolean isCollection() + { + return false; + } } diff --git a/src/main/java/org/reso/service/data/meta/ResourceInfo.java b/src/main/java/org/reso/service/data/meta/ResourceInfo.java index a0259bd..d5e398d 100644 --- a/src/main/java/org/reso/service/data/meta/ResourceInfo.java +++ b/src/main/java/org/reso/service/data/meta/ResourceInfo.java @@ -66,10 +66,11 @@ public class ResourceInfo ResultSet pkColumns = connect.getMetaData().getPrimaryKeys(null, null, getTableName()); - while(pkColumns.next()) { + while(pkColumns.next()) + { String pkColumnName = pkColumns.getString("COLUMN_NAME"); Integer pkPosition = pkColumns.getInt("KEY_SEQ"); - LOG.info(""+pkColumnName+" is the "+pkPosition+". column of the primary key of the table "+tableName); + LOG.debug(""+pkColumnName+" is the "+pkPosition+". column of the primary key of the table "+tableName); primaryKey = pkColumnName; } diff --git a/src/main/java/org/reso/service/edmprovider/RESOedmProvider.java b/src/main/java/org/reso/service/edmprovider/RESOedmProvider.java index b4d7de4..fb62edc 100644 --- a/src/main/java/org/reso/service/edmprovider/RESOedmProvider.java +++ b/src/main/java/org/reso/service/edmprovider/RESOedmProvider.java @@ -1,12 +1,15 @@ package org.reso.service.edmprovider; +import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; import org.apache.olingo.commons.api.edm.FullQualifiedName; import org.apache.olingo.commons.api.edm.provider.*; +import org.reso.service.data.meta.EnumFieldInfo; import org.reso.service.data.meta.FieldInfo; import org.reso.service.data.meta.ResourceInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -15,7 +18,7 @@ public class RESOedmProvider extends CsdlAbstractEdmProvider { private ArrayList resourceList = new ArrayList(); // Service Namespace - public static final String NAMESPACE = "RESO.OData.Metadata"; + public static final String NAMESPACE = "org.reso.metadata"; // EDM Container public static final String CONTAINER_NAME = "Container"; @@ -53,7 +56,7 @@ public class RESOedmProvider extends CsdlAbstractEdmProvider { String fieldName = field.getFieldName(); - CsdlProperty property = new CsdlProperty().setName(fieldName).setType(field.getType()); + CsdlProperty property = new CsdlProperty().setName(fieldName).setType(field.getType()).setCollection(field.isCollection()); Integer maxLength = field.getMaxLength(); if (null!=maxLength) { @@ -157,11 +160,43 @@ public class RESOedmProvider extends CsdlAbstractEdmProvider CsdlSchema schema = new CsdlSchema(); schema.setNamespace(NAMESPACE); + CsdlSchema enumSchema = new CsdlSchema(); + enumSchema.setNamespace(NAMESPACE+".enums"); + // add EntityTypes List entityTypes = new ArrayList(); for (ResourceInfo defn :resourceList) { + ArrayList fields = defn.getFieldList(); + for (FieldInfo field : fields) + { + if (field instanceof EnumFieldInfo) + { + EnumFieldInfo enumField = (EnumFieldInfo) field; + + ArrayList values = enumField.getValues(); + + if (null!=values && values.size()>0) + { + CsdlEnumType type = new CsdlEnumType(); + ArrayList csdlMembers = new ArrayList<>(); + + for (String value: values) + { + csdlMembers.add(new CsdlEnumMember().setName(value)); + } + + type.setMembers(csdlMembers); + type.setName(enumField.getLookupName()); + type.setUnderlyingType(EdmPrimitiveTypeKind.Int64.getFullQualifiedName()); + + enumSchema.getEnumTypes().add(type); + } + + } + } + entityTypes.add(getEntityType(defn)); } @@ -174,6 +209,22 @@ public class RESOedmProvider extends CsdlAbstractEdmProvider List schemas = new ArrayList(); schemas.add(schema); +/** + // Example of how to create enum types. + CsdlEnumType type = new CsdlEnumType(); + type.setMembers(Arrays.asList( + new CsdlEnumMember().setName("LOW"), + new CsdlEnumMember().setName("MEDIUM").setValue("1") + )); + type.setName("EnumTest"); + type.setUnderlyingType(EdmPrimitiveTypeKind.Int64.getFullQualifiedName()); + + enumSchema.getEnumTypes().add(type); + + /**/ + schemas.add(enumSchema); + + return schemas; } diff --git a/src/main/java/org/reso/service/servlet/RESOservlet.java b/src/main/java/org/reso/service/servlet/RESOservlet.java index 696e3fa..83bb5e9 100644 --- a/src/main/java/org/reso/service/servlet/RESOservlet.java +++ b/src/main/java/org/reso/service/servlet/RESOservlet.java @@ -24,6 +24,7 @@ import java.lang.reflect.Constructor; import java.sql.Connection; import java.sql.DriverManager; import java.util.ArrayList; +import java.util.HashMap; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.*; @@ -33,11 +34,18 @@ public class RESOservlet extends HttpServlet { private static final long serialVersionUID = 1L; private static final Logger LOG = LoggerFactory.getLogger(RESOservlet.class); - private Connection connect = null; + private static Connection connect = null; private Validator validator = null; private OData odata = null; ODataHttpHandler handler = null; + public static HashMap resourceLookup = new HashMap<>(); + + public static Connection getConnection() + { + return connect; + } + @Override public void init() throws ServletException { @@ -97,6 +105,7 @@ public class RESOservlet extends HttpServlet ctor.setAccessible(true); ResourceInfo resource = (ResourceInfo)ctor.newInstance(); resources.add(resource); + resourceLookup.put(resource.getResourceName(), resource); resource.findPrimaryKey(this.connect); }