From bfbe39993fcfdc5292bdc716ec4fa8df7dbdbd99 Mon Sep 17 00:00:00 2001 From: Athou Date: Thu, 1 Aug 2013 17:11:57 +0200 Subject: [PATCH] use an annotation processor instead of a groovy script because of classloading issues --- pom.xml | 36 ++++--- .../com/commafeed/backend/dao/FeedDAO.java | 1 + .../commafeed/backend/model/UserSettings.java | 4 + .../com/commafeed/frontend/APIGenerator.java | 96 +++++++++++++++++++ .../com/commafeed/frontend/rest/Enums.java | 13 --- .../frontend/rest/resources/CategoryREST.java | 8 +- .../frontend/rest/resources/FeedREST.java | 8 +- src/main/script/SwaggerStaticGenerator.groovy | 5 +- src/main/webapp/api/index.html | 2 +- src/main/webapp/js/controllers.js | 2 +- 10 files changed, 135 insertions(+), 40 deletions(-) create mode 100644 src/main/java/com/commafeed/frontend/APIGenerator.java delete mode 100644 src/main/java/com/commafeed/frontend/rest/Enums.java diff --git a/pom.xml b/pom.xml index 7f14e2b6..b4e1f09a 100644 --- a/pom.xml +++ b/pom.xml @@ -138,6 +138,19 @@ target/generated-sources/metamodel + + doc + process-classes + + process + + + + com.commafeed.frontend.APIGenerator + + target/generated-sources/api-docs + + @@ -340,6 +353,12 @@ swagger-annotations_2.9.1 1.2.5 + + com.wordnik + swagger-jaxrs_2.9.1 + 1.2.5 + provided + junit @@ -471,15 +490,10 @@ commons-io 2.4 - - com.wordnik - swagger-jaxrs_2.9.1 - 1.2.5 - - generate-sources + process-classes execute @@ -489,7 +503,6 @@ templates/ ${basedir}/target/generated-sources/angularjs/all-templates.html ${basedir}/src/main/resources/i18n/ - ${basedir}/target/generated-sources/swagger-doc ${basedir}/src/main/script @@ -505,11 +518,6 @@ new HTMLConcat().concat(source, prefix, dest, i18n); - - def docPath = - project.properties['doc.path']; - new - SwaggerStaticGenerator().generate(docPath); @@ -545,8 +553,8 @@ - target/generated-sources/swagger-doc/ - api/swagger-doc + target/generated-sources/api-docs/ + api/api-docs **/* diff --git a/src/main/java/com/commafeed/backend/dao/FeedDAO.java b/src/main/java/com/commafeed/backend/dao/FeedDAO.java index b72f6776..20d576ab 100644 --- a/src/main/java/com/commafeed/backend/dao/FeedDAO.java +++ b/src/main/java/com/commafeed/backend/dao/FeedDAO.java @@ -103,6 +103,7 @@ public class FeedDAO extends GenericDAO { } + @XmlRootElement public static enum DuplicateMode { NORMALIZED_URL(Feed_.normalizedUrlHash), LAST_CONTENT(Feed_.lastContentHash), PUSH_TOPIC(Feed_.pushTopicHash); private SingularAttribute path; diff --git a/src/main/java/com/commafeed/backend/model/UserSettings.java b/src/main/java/com/commafeed/backend/model/UserSettings.java index f68c9664..eac3c3b3 100644 --- a/src/main/java/com/commafeed/backend/model/UserSettings.java +++ b/src/main/java/com/commafeed/backend/model/UserSettings.java @@ -10,6 +10,7 @@ import javax.persistence.JoinColumn; import javax.persistence.Lob; import javax.persistence.OneToOne; import javax.persistence.Table; +import javax.xml.bind.annotation.XmlRootElement; import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; @@ -21,14 +22,17 @@ import org.hibernate.annotations.CacheConcurrencyStrategy; @Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) public class UserSettings extends AbstractModel { + @XmlRootElement public enum ReadingMode { all, unread } + @XmlRootElement public enum ReadingOrder { asc, desc } + @XmlRootElement public enum ViewMode { title, expanded } diff --git a/src/main/java/com/commafeed/frontend/APIGenerator.java b/src/main/java/com/commafeed/frontend/APIGenerator.java new file mode 100644 index 00000000..5a8ea53d --- /dev/null +++ b/src/main/java/com/commafeed/frontend/APIGenerator.java @@ -0,0 +1,96 @@ +package com.commafeed.frontend; + +import java.io.File; +import java.util.Set; + +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.annotation.processing.SupportedOptions; +import javax.lang.model.element.Element; +import javax.lang.model.element.TypeElement; +import javax.tools.Diagnostic.Kind; +import javax.tools.FileObject; +import javax.tools.StandardLocation; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang.StringUtils; + +import com.commafeed.frontend.model.Entries; +import com.commafeed.frontend.model.request.MarkRequest; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.core.Documentation; +import com.wordnik.swagger.core.DocumentationEndPoint; +import com.wordnik.swagger.core.SwaggerSpec; +import com.wordnik.swagger.core.util.TypeUtil; +import com.wordnik.swagger.jaxrs.HelpApi; +import com.wordnik.swagger.jaxrs.JaxrsApiReader; + +@SupportedAnnotationTypes("com.wordnik.swagger.annotations.Api") +@SupportedOptions("outputDirectory") +public class APIGenerator extends AbstractProcessor { + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + try { + return processInternal(annotations, roundEnv); + } catch (Exception e) { + e.printStackTrace(); + processingEnv.getMessager().printMessage(Kind.ERROR, e.getMessage()); + } + return false; + } + + private boolean processInternal(Set annotations, RoundEnvironment roundEnv) throws Exception { + JaxrsApiReader.setFormatString(""); + TypeUtil.addAllowablePackage(Entries.class.getPackage().getName()); + TypeUtil.addAllowablePackage(MarkRequest.class.getPackage().getName()); + + String apiVersion = "1.0"; + String swaggerVersion = SwaggerSpec.version(); + String basePath = "../rest"; + + Documentation doc = new Documentation(); + for (Element element : roundEnv.getElementsAnnotatedWith(Api.class)) { + TypeElement type = (TypeElement) element; + String fqn = type.getQualifiedName().toString(); + Class resource = Class.forName(fqn); + + Api api = resource.getAnnotation(Api.class); + String apiPath = api.value(); + + Documentation apiDoc = JaxrsApiReader.read(resource, apiVersion, swaggerVersion, basePath, apiPath); + apiDoc = new HelpApi(null).filterDocs(apiDoc, null, null, null, null); + + apiDoc.setSwaggerVersion(swaggerVersion); + apiDoc.setApiVersion(apiVersion); + write(apiDoc, element); + + doc.addApi(new DocumentationEndPoint(api.value(), api.description())); + + } + doc.setSwaggerVersion(swaggerVersion); + doc.setApiVersion(apiVersion); + + write(doc, null); + + return true; + } + + private void write(Documentation doc, Element element) throws Exception { + String fileName = doc.getResourcePath() == null ? "resources" : doc.getResourcePath(); + fileName = StringUtils.removeStart(fileName, "/"); + + FileObject resource = null; + try { + resource = processingEnv.getFiler().createResource(StandardLocation.SOURCE_OUTPUT, "", fileName, element); + } catch (Exception e) { + // already processed + } + if (resource != null) { + FileUtils.writeStringToFile(new File(resource.toUri()), new ObjectMapper().writeValueAsString(doc)); + } + + } +} diff --git a/src/main/java/com/commafeed/frontend/rest/Enums.java b/src/main/java/com/commafeed/frontend/rest/Enums.java deleted file mode 100644 index fc590d29..00000000 --- a/src/main/java/com/commafeed/frontend/rest/Enums.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.commafeed.frontend.rest; - -public class Enums { - - public enum Type { - category, feed, entry; - } - - public enum ReadType { - all, unread; - } - -} diff --git a/src/main/java/com/commafeed/frontend/rest/resources/CategoryREST.java b/src/main/java/com/commafeed/frontend/rest/resources/CategoryREST.java index 4be2cc2b..331434dd 100644 --- a/src/main/java/com/commafeed/frontend/rest/resources/CategoryREST.java +++ b/src/main/java/com/commafeed/frontend/rest/resources/CategoryREST.java @@ -32,6 +32,7 @@ import com.commafeed.backend.model.FeedEntryStatus; import com.commafeed.backend.model.FeedSubscription; import com.commafeed.backend.model.User; import com.commafeed.backend.model.UserRole.Role; +import com.commafeed.backend.model.UserSettings.ReadingMode; import com.commafeed.backend.model.UserSettings.ReadingOrder; import com.commafeed.backend.services.ApplicationSettingsService; import com.commafeed.backend.services.FeedEntryService; @@ -47,7 +48,6 @@ import com.commafeed.frontend.model.request.CategoryModificationRequest; import com.commafeed.frontend.model.request.CollapseRequest; import com.commafeed.frontend.model.request.IDRequest; import com.commafeed.frontend.model.request.MarkRequest; -import com.commafeed.frontend.rest.Enums.ReadType; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import com.sun.syndication.feed.synd.SyndEntry; @@ -98,7 +98,7 @@ public class CategoryREST extends AbstractREST { @ApiParam(value = "id of the category, 'all' or 'starred'", required = true) @QueryParam("id") String id, @ApiParam( value = "all entries or only unread ones", allowableValues = "all,unread", - required = true) @DefaultValue("unread") @QueryParam("readType") ReadType readType, @ApiParam( + required = true) @DefaultValue("unread") @QueryParam("readType") ReadingMode readType, @ApiParam( value = "only entries newer than this") @QueryParam("newerThan") Long newerThan, @ApiParam(value = "offset for paging") @DefaultValue("0") @QueryParam("offset") int offset, @ApiParam( value = "limit for paging, default 20, maximum 50") @DefaultValue("20") @QueryParam("limit") int limit, @ApiParam( @@ -112,7 +112,7 @@ public class CategoryREST extends AbstractREST { Entries entries = new Entries(); entries.setOffset(offset); entries.setLimit(limit); - boolean unreadOnly = readType == ReadType.unread; + boolean unreadOnly = readType == ReadingMode.unread; if (StringUtils.isBlank(id)) { id = ALL; } @@ -175,7 +175,7 @@ public class CategoryREST extends AbstractREST { Preconditions.checkNotNull(id); - ReadType readType = ReadType.all; + ReadingMode readType = ReadingMode.all; ReadingOrder order = ReadingOrder.desc; int offset = 0; int limit = 20; diff --git a/src/main/java/com/commafeed/frontend/rest/resources/FeedREST.java b/src/main/java/com/commafeed/frontend/rest/resources/FeedREST.java index 04de9bc6..d630d377 100644 --- a/src/main/java/com/commafeed/frontend/rest/resources/FeedREST.java +++ b/src/main/java/com/commafeed/frontend/rest/resources/FeedREST.java @@ -54,6 +54,7 @@ import com.commafeed.backend.model.FeedCategory; import com.commafeed.backend.model.FeedEntryStatus; import com.commafeed.backend.model.FeedSubscription; import com.commafeed.backend.model.UserRole.Role; +import com.commafeed.backend.model.UserSettings.ReadingMode; import com.commafeed.backend.model.UserSettings.ReadingOrder; import com.commafeed.backend.services.ApplicationSettingsService; import com.commafeed.backend.services.FeedEntryService; @@ -68,7 +69,6 @@ import com.commafeed.frontend.model.request.FeedModificationRequest; import com.commafeed.frontend.model.request.IDRequest; import com.commafeed.frontend.model.request.MarkRequest; import com.commafeed.frontend.model.request.SubscribeRequest; -import com.commafeed.frontend.rest.Enums.ReadType; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import com.sun.syndication.feed.opml.Opml; @@ -135,7 +135,7 @@ public class FeedREST extends AbstractREST { public Response getFeedEntries(@ApiParam(value = "id of the feed", required = true) @QueryParam("id") String id, @ApiParam( value = "all entries or only unread ones", allowableValues = "all,unread", - required = true) @DefaultValue("unread") @QueryParam("readType") ReadType readType, @ApiParam( + required = true) @DefaultValue("unread") @QueryParam("readType") ReadingMode readType, @ApiParam( value = "only entries newer than this") @QueryParam("newerThan") Long newerThan, @ApiParam(value = "offset for paging") @DefaultValue("0") @QueryParam("offset") int offset, @ApiParam( value = "limit for paging, default 20, maximum 50") @DefaultValue("20") @QueryParam("limit") int limit, @ApiParam( @@ -152,7 +152,7 @@ public class FeedREST extends AbstractREST { entries.setOffset(offset); entries.setLimit(limit); - boolean unreadOnly = readType == ReadType.unread; + boolean unreadOnly = readType == ReadingMode.unread; Date newerThanDate = newerThan == null ? null : new Date(Long.valueOf(newerThan)); @@ -192,7 +192,7 @@ public class FeedREST extends AbstractREST { Preconditions.checkNotNull(id); - ReadType readType = ReadType.all; + ReadingMode readType = ReadingMode.all; ReadingOrder order = ReadingOrder.desc; int offset = 0; int limit = 20; diff --git a/src/main/script/SwaggerStaticGenerator.groovy b/src/main/script/SwaggerStaticGenerator.groovy index a0dec1d2..5f82ba1c 100644 --- a/src/main/script/SwaggerStaticGenerator.groovy +++ b/src/main/script/SwaggerStaticGenerator.groovy @@ -32,10 +32,9 @@ public class SwaggerStaticGenerator { Api api = resource.getAnnotation(Api.class); if (api != null) { String apiPath = api.value(); - String apiListingPath = api.value(); - Documentation apiDoc = new HelpApi(null).filterDocs( - JaxrsApiReader.read(resource, apiVersion, swaggerVersion, basePath, apiPath), null, null, apiListingPath, apiPath); + Documentation apiDoc = JaxrsApiReader.read(resource, apiVersion, swaggerVersion, basePath, apiPath); + apiDoc = new HelpApi(null).filterDocs(apiDoc, null, null, null, null); apiDoc.setSwaggerVersion(swaggerVersion); apiDoc.setApiVersion(apiVersion); diff --git a/src/main/webapp/api/index.html b/src/main/webapp/api/index.html index 449e09a6..c358be92 100644 --- a/src/main/webapp/api/index.html +++ b/src/main/webapp/api/index.html @@ -29,7 +29,7 @@ link.attr('href', url + '/rest'); link.html(link.attr('href')); - url = url + '/api/swagger-doc/resources'; + url = url + '/api/api-docs/resources'; window.swaggerUi = new SwaggerUi({ discoveryUrl:url, apiKey:"", diff --git a/src/main/webapp/js/controllers.js b/src/main/webapp/js/controllers.js index b17961d2..15dcdf23 100644 --- a/src/main/webapp/js/controllers.js +++ b/src/main/webapp/js/controllers.js @@ -721,7 +721,7 @@ module.controller('FeedListCtrl', [ } var callback = function(data) { - if (data.offset == 0) { + if (data.offset === 0) { $scope.entries = []; } for ( var i = 0; i < data.entries.length; i++) {