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 extends TypeElement> 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 extends TypeElement> 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++) {