Skip to content

Commit

Permalink
Merge pull request #270 from KaiVolland/decribe-model
Browse files Browse the repository at this point in the history
Introduces "describeModel" interface.
  • Loading branch information
KaiVolland authored Nov 24, 2017
2 parents 257a7ab + 991a892 commit 0b3c383
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 8 deletions.
6 changes: 6 additions & 0 deletions src/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,12 @@
<version>${jackson-datatype-jts.version}</version>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-jsonSchema</artifactId>
<version>${jackson.version}</version>
</dependency>

<!-- CSV -->
<dependency>
<groupId>com.opencsv</groupId>
Expand Down
4 changes: 4 additions & 0 deletions src/shogun2-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,10 @@
<groupId>com.bedatadriven</groupId>
<artifactId>jackson-datatype-jts</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-jsonSchema</artifactId>
</dependency>

<!-- CSV -->
<dependency>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package de.terrestris.shogun2.service;

import java.io.IOException;
import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.module.jsonSchema.JsonSchema;
import com.fasterxml.jackson.module.jsonSchema.JsonSchemaGenerator;


/**
* Service class to describe classes model.
*
* terrestris GmbH & Co. KG
* @author Kai Volland
* @date 04.09.2017
*
*/
@Service("modelDescriptionService")
public class ModelDescriptionService {

/**
* The LOGGER instance (that will be available in all subclasses)
*/
protected final Logger LOG = Logger.getLogger(getClass());

@Resource
@Qualifier("describeModelSearchPackages")
private List<String> describeModelSearchPackages;

/**
*
*/
@Autowired
protected ObjectMapper objectMapper;

public JsonSchema getJsonSchema(String className) throws IOException {

Class<?> foundClass = null;
for (String searchPackage : describeModelSearchPackages) {
LOG.debug(String.format("Search className %s in package %s.", className, searchPackage));
try{
boolean wasNull = foundClass == null;
foundClass = Class.forName(searchPackage + "." + className);
if (!wasNull) {
LOG.error(String.format("Modelname %s exists in multiple packages! Last one will win.", className));
}
} catch (ClassNotFoundException e){
//not in this package, try another
}
}

if (foundClass == null) {
LOG.warn(String.format("No class found for describing modelname %s", className));
return null;
}

JsonSchemaGenerator schemaGen = new JsonSchemaGenerator(objectMapper);
JsonSchema schema = schemaGen.generateSchema(foundClass);

return schema;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package de.terrestris.shogun2.web;

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.fasterxml.jackson.module.jsonSchema.JsonSchema;

import de.terrestris.shogun2.service.ModelDescriptionService;
import de.terrestris.shogun2.util.data.ResultSet;

/**
*
* terrestris GmbH & Co. KG
* @author Kai Volland
* @date 04.09.2017
*
*
*/
@Controller
@RequestMapping("/describeModel")
public class ModelDescriptionController {

@Autowired
@Qualifier("modelDescriptionService")
private ModelDescriptionService modelDescriptionService;

@RequestMapping(value = "/asJson/{className}.action", method = RequestMethod.GET)
public @ResponseBody Map<String, Object> getJsonSchema(@PathVariable String className) {
try {
JsonSchema json = modelDescriptionService.getJsonSchema(className);
if (json == null) {
return ResultSet.error("Modeldescription (json) for model " + className + "is null.");
}
return ResultSet.success(json);
} catch (Exception e) {
return ResultSet.error("Could not get description for " + className + " " + e.getMessage());
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,15 @@
<!-- The GeoServer Namespace to URI map used in the Interceptor -->
<util:properties id="geoServerNameSpaces" location="classpath*:META-INF/geoServerNameSpaces.properties" />

<!-- The Shogun2JsonObjectMapper -->
<bean id="jacksonObjectMapper" class="de.terrestris.shogun2.util.json.Shogun2JsonObjectMapper" />

<!-- The SearchPackages to be used in the modelDescriptionService -->
<util:list id="describeModelSearchPackages" value-type="java.lang.String">
<value>de.terrestris.shogun2.model</value>
<value>${package}.model</value>
</util:list>

<!--
| The interceptor beans, uncomment to be able to use the interceptor
| classes for OGC requests
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ ${shogun2-parent-package}.*.web" )
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

<!-- This tag registers the DefaultAnnotationHandlerMapping and AnnotationMethodHandlerAdapter
<!-- This tag registers the DefaultAnnotationHandlerMapping and AnnotationMethodHandlerAdapter
beans that are required for Spring MVC -->
<mvc:annotation-driven
content-negotiation-manager="contentNegotiationManager">
<!-- Use customized Jackson/JSON Object Mapper, e.g. for a nicer joda date
<!-- Use customized Jackson/JSON Object Mapper, e.g. for a nicer joda date
serialization -->
<mvc:message-converters>
<beans:bean
Expand All @@ -34,8 +34,8 @@ ${shogun2-parent-package}.*.web" )
</mvc:message-converters>
</mvc:annotation-driven>

<!-- Use this bean (referenced above) to map our .action extension to the
application/json mime type. This is necessary since Spring 4.2.2 See: https://pivotal.io/security/cve-2015-5211
<!-- Use this bean (referenced above) to map our .action extension to the
application/json mime type. This is necessary since Spring 4.2.2 See: https://pivotal.io/security/cve-2015-5211
TODO: We should discuss, if this is really what we want. -->
<beans:bean id="contentNegotiationManager"
class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
Expand All @@ -47,13 +47,10 @@ ${shogun2-parent-package}.*.web" )
</beans:bean>

<annotation-config />

<beans:bean id="requestHandlerMapping"
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />

<beans:bean id="jacksonObjectMapper"
class="de.terrestris.shogun2.util.json.Shogun2JsonObjectMapper" />

<component-scan base-package="${web_packages_to_scan}" use-default-filters="false">
<include-filter expression="org.springframework.stereotype.Controller" type="annotation" />
</component-scan>
Expand Down

0 comments on commit 0b3c383

Please sign in to comment.