documentation is now generated during build time and swagger is not needed for runtime anymore

This commit is contained in:
Athou
2013-08-01 13:35:04 +02:00
parent 0ff1d58dfb
commit 8926f9784d
29 changed files with 128 additions and 430 deletions

59
pom.xml
View File

@@ -237,16 +237,6 @@
<artifactId>commons-fileupload</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>com.googlecode.lambdaj</groupId>
<artifactId>lambdaj</artifactId>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>net.java.dev.rome</groupId>
@@ -291,17 +281,6 @@
<version>0.9.9</version>
</dependency>
<dependency>
<groupId>com.google.oauth-client</groupId>
<artifactId>google-oauth-client-servlet</artifactId>
<version>1.14.1-beta</version>
</dependency>
<dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client-jackson2</artifactId>
<version>1.14.1-beta</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
@@ -358,26 +337,8 @@
<dependency>
<groupId>com.wordnik</groupId>
<artifactId>swagger-jaxrs_2.9.1</artifactId>
<artifactId>swagger-annotations_2.9.1</artifactId>
<version>1.2.5</version>
<exclusions>
<exclusion>
<artifactId>jersey-server</artifactId>
<groupId>com.sun.jersey</groupId>
</exclusion>
<exclusion>
<artifactId>jersey-servlet</artifactId>
<groupId>com.sun.jersey</groupId>
</exclusion>
<exclusion>
<artifactId>jersey-client</artifactId>
<groupId>com.sun.jersey</groupId>
</exclusion>
<exclusion>
<artifactId>jersey-core</artifactId>
<groupId>com.sun.jersey</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
@@ -510,6 +471,11 @@
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>com.wordnik</groupId>
<artifactId>swagger-jaxrs_2.9.1</artifactId>
<version>1.2.5</version>
</dependency>
</dependencies>
<executions>
<execution>
@@ -523,6 +489,7 @@
<prefix>templates/</prefix>
<destination>${basedir}/target/generated-sources/angularjs/all-templates.html</destination>
<i18nPath>${basedir}/src/main/resources/i18n/</i18nPath>
<doc.path>${basedir}/target/generated-sources/swagger-doc</doc.path>
</properties>
<scriptpath>
<element>${basedir}/src/main/script</element>
@@ -538,6 +505,11 @@
new
HTMLConcat().concat(source,
prefix, dest, i18n);
def docPath =
project.properties['doc.path'];
new
SwaggerStaticGenerator().generate(docPath);
</source>
</configuration>
</execution>
@@ -572,6 +544,13 @@
<include>**/*.html</include>
</includes>
</resource>
<resource>
<directory>target/generated-sources/swagger-doc/</directory>
<targetPath>api/swagger-doc</targetPath>
<includes>
<include>**/*</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>

View File

@@ -23,7 +23,7 @@ import com.commafeed.backend.model.ApplicationSettings;
import com.commafeed.backend.model.UserRole.Role;
import com.commafeed.backend.services.ApplicationSettingsService;
import com.commafeed.backend.services.UserService;
import com.google.api.client.util.Maps;
import com.google.common.collect.Maps;
/**
* Starting point of the application

View File

@@ -22,7 +22,7 @@ import com.commafeed.backend.model.User;
import com.commafeed.frontend.model.Category;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.api.client.util.Lists;
import com.google.common.collect.Lists;
@Alternative
@ApplicationScoped

View File

@@ -21,8 +21,8 @@ import com.commafeed.backend.MetricsBean;
import com.commafeed.backend.dao.FeedDAO;
import com.commafeed.backend.model.Feed;
import com.commafeed.backend.services.ApplicationSettingsService;
import com.google.api.client.util.Maps;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Queues;
/**

View File

@@ -34,7 +34,7 @@ import com.commafeed.backend.model.User;
import com.commafeed.backend.pubsubhubbub.SubscriptionHandler;
import com.commafeed.backend.services.ApplicationSettingsService;
import com.commafeed.backend.services.FeedUpdateService;
import com.google.api.client.util.Lists;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.Striped;
@ApplicationScoped

View File

@@ -8,6 +8,7 @@ import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
@@ -28,8 +29,7 @@ import org.w3c.dom.css.CSSStyleDeclaration;
import com.commafeed.backend.model.FeedEntry;
import com.commafeed.backend.model.FeedSubscription;
import com.google.api.client.util.Base64;
import com.google.api.client.util.Lists;
import com.google.common.collect.Lists;
import com.google.gwt.i18n.client.HasDirection.Direction;
import com.google.gwt.i18n.shared.BidiUtils;
import com.steadystate.css.parser.CSSOMParser;

View File

@@ -4,7 +4,7 @@ import java.util.List;
import com.commafeed.backend.model.Feed;
import com.commafeed.backend.model.FeedEntry;
import com.google.api.client.util.Lists;
import com.google.common.collect.Lists;
public class FetchedFeed {

View File

@@ -21,7 +21,7 @@ import com.commafeed.backend.model.FeedCategory;
import com.commafeed.backend.model.FeedSubscription;
import com.commafeed.backend.model.Models;
import com.commafeed.backend.model.User;
import com.google.api.client.util.Maps;
import com.google.common.collect.Maps;
public class FeedSubscriptionService {

View File

@@ -69,9 +69,6 @@ public class CommaFeedApplication extends AuthenticatedWebApplication {
mountPage("logout", LogoutPage.class);
mountPage("error", DisplayExceptionPage.class);
// mountPage("google/import/redirect", GoogleImportRedirectPage.class);
// mountPage(GoogleImportCallbackPage.PAGE_PATH, GoogleImportCallbackPage.class);
mountPage("next", NextUnreadRedirectPage.class);
setupInjection();

View File

@@ -7,7 +7,7 @@ import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import com.google.api.client.util.Maps;
import com.google.common.collect.Maps;
import com.wordnik.swagger.annotations.ApiClass;
@SuppressWarnings("serial")

View File

@@ -31,7 +31,7 @@ import com.commafeed.backend.services.ApplicationSettingsService;
import com.commafeed.backend.services.MailService;
import com.commafeed.frontend.CommaFeedSession;
import com.commafeed.frontend.utils.WicketUtils;
import com.google.api.client.util.Maps;
import com.google.common.collect.Maps;
@SuppressWarnings("serial")
public abstract class BasePage extends WebPage {

View File

@@ -1,105 +0,0 @@
package com.commafeed.frontend.pages;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import org.apache.wicket.RestartResponseException;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import com.commafeed.backend.StartupBean;
import com.commafeed.backend.dao.UserDAO;
import com.commafeed.backend.feeds.FeedUtils;
import com.commafeed.backend.feeds.OPMLImporter;
import com.commafeed.backend.model.ApplicationSettings;
import com.commafeed.backend.model.User;
import com.commafeed.backend.services.ApplicationSettingsService;
import com.commafeed.frontend.CommaFeedSession;
import com.commafeed.frontend.utils.WicketUtils;
import com.commafeed.frontend.utils.exception.DisplayException;
import com.google.api.client.auth.oauth2.AuthorizationCodeResponseUrl;
import com.google.api.client.auth.oauth2.AuthorizationCodeTokenRequest;
import com.google.api.client.auth.oauth2.BearerToken;
import com.google.api.client.auth.oauth2.TokenResponse;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
@SuppressWarnings("serial")
public class GoogleImportCallbackPage extends WebPage {
private static final String TOKEN_URL = "https://accounts.google.com/o/oauth2/token";
private static final String EXPORT_URL = "https://www.google.com/reader/subscriptions/export";
public static final String PAGE_PATH = "google/import/callback";
@Inject
ApplicationSettingsService applicationSettingsService;
@Inject
OPMLImporter importer;
@Inject
UserDAO userDAO;
public static String getCallbackUrl(String publicUrl) {
return FeedUtils.removeTrailingSlash(publicUrl) + "/" + PAGE_PATH;
}
public GoogleImportCallbackPage(PageParameters params) {
HttpServletRequest request = WicketUtils.getHttpServletRequest();
StringBuffer urlBuffer = request.getRequestURL();
if (request.getQueryString() != null) {
urlBuffer.append('?').append(request.getQueryString());
}
AuthorizationCodeResponseUrl responseUrl = new AuthorizationCodeResponseUrl(urlBuffer.toString());
String code = responseUrl.getCode();
if (responseUrl.getError() != null) {
// user declined
throw new RestartResponseException(getApplication().getHomePage());
} else if (code == null) {
throw new DisplayException("Missing authorization code");
} else {
ApplicationSettings settings = applicationSettingsService.get();
String redirectUri = getCallbackUrl(settings.getPublicUrl());
String clientId = settings.getGoogleClientId();
String clientSecret = settings.getGoogleClientSecret();
HttpTransport httpTransport = new NetHttpTransport();
JacksonFactory jsonFactory = new JacksonFactory();
AuthorizationCodeTokenRequest tokenRequest = new AuthorizationCodeTokenRequest(httpTransport, jsonFactory, new GenericUrl(
TOKEN_URL), code);
tokenRequest.setRedirectUri(redirectUri);
tokenRequest.put("client_id", clientId);
tokenRequest.put("client_secret", clientSecret);
tokenRequest.setGrantType("authorization_code");
try {
// potential fix for invalid_grant error, happens if local
// system time is ahead of google servers time
Thread.sleep(1000);
TokenResponse tokenResponse = tokenRequest.execute();
String accessToken = tokenResponse.getAccessToken();
HttpRequest httpRequest = httpTransport.createRequestFactory().buildGetRequest(new GenericUrl(EXPORT_URL));
BearerToken.authorizationHeaderAccessMethod().intercept(httpRequest, accessToken);
String opml = httpRequest.execute().parseAsString();
User user = CommaFeedSession.get().getUser();
if (user != null) {
if (StartupBean.USERNAME_DEMO.equals(user.getName())) {
throw new DisplayException("Import is disabled for the demo account");
}
importer.importOpml(CommaFeedSession.get().getUser(), opml);
}
} catch (Exception e) {
throw new DisplayException(e);
}
}
setResponsePage(getApplication().getHomePage());
}
}

View File

@@ -1,49 +0,0 @@
package com.commafeed.frontend.pages;
import java.net.URISyntaxException;
import javax.inject.Inject;
import org.apache.http.client.utils.URIBuilder;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.request.flow.RedirectToUrlException;
import org.jboss.logging.Logger;
import com.commafeed.backend.model.ApplicationSettings;
import com.commafeed.backend.services.ApplicationSettingsService;
@SuppressWarnings("serial")
public class GoogleImportRedirectPage extends WebPage {
private static Logger log = Logger.getLogger(GoogleImportRedirectPage.class);
private static final String SCOPE = "https://www.google.com/reader/subscriptions/export email profile";
private static final String AUTH_URL = "https://accounts.google.com/o/oauth2/auth";
@Inject
ApplicationSettingsService applicationSettingsService;
public GoogleImportRedirectPage() {
ApplicationSettings settings = applicationSettingsService.get();
String clientId = settings.getGoogleClientId();
String redirectUri = GoogleImportCallbackPage.getCallbackUrl(settings.getPublicUrl());
try {
URIBuilder builder = new URIBuilder(AUTH_URL);
builder.addParameter("redirect_uri", redirectUri);
builder.addParameter("response_type", "code");
builder.addParameter("scope", SCOPE);
builder.addParameter("approval_prompt", "force");
builder.addParameter("client_id", clientId);
builder.addParameter("access_type", "offline");
throw new RedirectToUrlException(builder.build().toString());
} catch (URISyntaxException e) {
log.error(e.getMessage(), e);
}
}
}

View File

@@ -14,6 +14,7 @@ import org.apache.wicket.markup.html.form.StatelessForm;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.validation.IValidatable;
import org.apache.wicket.validation.IValidator;
import org.apache.wicket.validation.ValidationError;
@@ -26,7 +27,6 @@ import com.commafeed.backend.services.ApplicationSettingsService;
import com.commafeed.backend.services.UserService;
import com.commafeed.frontend.CommaFeedSession;
import com.commafeed.frontend.model.request.RegistrationRequest;
import com.commafeed.frontend.utils.ModelFactory.MF;
@SuppressWarnings("serial")
public class RegisterPanel extends Panel {
@@ -62,9 +62,8 @@ public class RegisterPanel extends Panel {
add(form);
add(new BootstrapFeedbackPanel("feedback", new ContainerFeedbackMessageFilter(form)));
RegistrationRequest p = MF.p(RegistrationRequest.class);
form.add(new RequiredTextField<String>("name", MF.m(model, p.getName())).add(StringValidator.lengthBetween(3, 32)).add(
new IValidator<String>() {
form.add(new RequiredTextField<String>("name", new PropertyModel<String>(model, "name")).add(StringValidator.lengthBetween(3, 32))
.add(new IValidator<String>() {
@Override
public void validate(IValidatable<String> validatable) {
String name = validatable.getValue();
@@ -74,9 +73,9 @@ public class RegisterPanel extends Panel {
}
}
}));
form.add(new PasswordTextField("password", MF.m(model, p.getPassword())).setResetPassword(false).add(
form.add(new PasswordTextField("password", new PropertyModel<String>(model, "password")).setResetPassword(false).add(
StringValidator.minimumLength(6)));
form.add(new RequiredTextField<String>("email", MF.m(model, p.getEmail())) {
form.add(new RequiredTextField<String>("email", new PropertyModel<String>(model, "email")) {
@Override
protected String getInputType() {
return "email";

View File

@@ -6,7 +6,7 @@ import ro.isdc.wro.model.resource.processor.ResourcePostProcessor;
import ro.isdc.wro.model.resource.processor.ResourcePreProcessor;
import ro.isdc.wro.model.resource.processor.support.ProcessorProvider;
import com.google.api.client.util.Maps;
import com.google.common.collect.Maps;
/**
* Build-time solution

View File

@@ -6,7 +6,6 @@ import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import com.commafeed.frontend.rest.resources.AdminREST;
import com.commafeed.frontend.rest.resources.ApiDocumentationREST;
import com.commafeed.frontend.rest.resources.CategoryREST;
import com.commafeed.frontend.rest.resources.EntryREST;
import com.commafeed.frontend.rest.resources.FeedREST;
@@ -14,15 +13,10 @@ import com.commafeed.frontend.rest.resources.PubSubHubbubCallbackREST;
import com.commafeed.frontend.rest.resources.ServerREST;
import com.commafeed.frontend.rest.resources.UserREST;
import com.google.common.collect.Sets;
import com.wordnik.swagger.jaxrs.JaxrsApiReader;
@ApplicationPath("/rest")
public class RESTApplication extends Application {
static {
JaxrsApiReader.setFormatString("");
}
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> set = Sets.newHashSet();
@@ -35,7 +29,6 @@ public class RESTApplication extends Application {
set.add(ServerREST.class);
set.add(AdminREST.class);
set.add(ApiDocumentationREST.class);
set.add(PubSubHubbubCallbackREST.class);
return set;

View File

@@ -33,6 +33,7 @@ import com.commafeed.frontend.SecurityCheck;
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@SecurityCheck(Role.USER)
public abstract class AbstractREST {
@Context

View File

@@ -1,77 +0,0 @@
package com.commafeed.frontend.rest.resources;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.UriInfo;
import org.apache.commons.lang.StringUtils;
import com.commafeed.backend.model.UserRole.Role;
import com.commafeed.backend.services.ApplicationSettingsService;
import com.commafeed.frontend.SecurityCheck;
import com.commafeed.frontend.model.Entries;
import com.commafeed.frontend.model.request.MarkRequest;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.core.Documentation;
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;
@SecurityCheck(Role.USER)
public abstract class AbstractResourceREST extends AbstractREST {
@Inject
ApplicationSettingsService applicationSettingsService;
@GET
@SecurityCheck(value = Role.NONE)
@ApiOperation(value = "Returns information about API parameters", responseClass = "com.wordnik.swagger.core.Documentation")
public Response getHelp(@Context Application app, @Context HttpHeaders headers, @Context UriInfo uriInfo) {
TypeUtil.addAllowablePackage(Entries.class.getPackage().getName());
TypeUtil.addAllowablePackage(MarkRequest.class.getPackage().getName());
String apiVersion = ApiDocumentationREST.API_VERSION;
String swaggerVersion = SwaggerSpec.version();
String basePath = ApiDocumentationREST.getBasePath(applicationSettingsService.get().getPublicUrl());
Class<?> resource = null;
String path = prependSlash(uriInfo.getPath());
for (Class<?> klass : app.getClasses()) {
Api api = klass.getAnnotation(Api.class);
if (api != null && api.value() != null && StringUtils.equals(prependSlash(api.value()), path)) {
resource = klass;
break;
}
}
if (resource == null) {
return Response.status(Status.NOT_FOUND).entity("Api annotation not found on class " + getClass().getName()).build();
}
Api api = resource.getAnnotation(Api.class);
String apiPath = api.value();
String apiListingPath = api.value();
Documentation doc = new HelpApi(null).filterDocs(JaxrsApiReader.read(resource, apiVersion, swaggerVersion, basePath, apiPath),
headers, uriInfo, apiListingPath, apiPath);
doc.setSwaggerVersion(swaggerVersion);
doc.setBasePath(basePath);
doc.setApiVersion(apiVersion);
return Response.ok().entity(doc).build();
}
private String prependSlash(String path) {
if (!path.startsWith("/")) {
path = "/" + path;
}
return path;
}
}

View File

@@ -33,6 +33,7 @@ import com.commafeed.backend.model.Feed;
import com.commafeed.backend.model.User;
import com.commafeed.backend.model.UserRole;
import com.commafeed.backend.model.UserRole.Role;
import com.commafeed.backend.services.ApplicationSettingsService;
import com.commafeed.backend.services.FeedService;
import com.commafeed.backend.services.PasswordEncryptionService;
import com.commafeed.backend.services.UserService;
@@ -51,7 +52,7 @@ import com.wordnik.swagger.annotations.ApiParam;
@SecurityCheck(Role.ADMIN)
@Path("/admin")
@Api(value = "/admin", description = "Operations about application administration")
public class AdminREST extends AbstractResourceREST {
public class AdminREST extends AbstractREST {
@Inject
FeedService feedService;
@@ -86,6 +87,9 @@ public class AdminREST extends AbstractResourceREST {
@Inject
PasswordEncryptionService encryptionService;
@Inject
ApplicationSettingsService applicationSettingsService;
@Path("/user/save")
@POST
@ApiOperation(value = "Save or update a user", notes = "Save or update a user. If the id is not specified, a new user will be created")

View File

@@ -1,63 +0,0 @@
package com.commafeed.frontend.rest.resources;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import com.commafeed.backend.services.ApplicationSettingsService;
import com.commafeed.frontend.model.Entries;
import com.commafeed.frontend.model.request.MarkRequest;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
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;
@Path("/resources")
@Api("/resources")
public class ApiDocumentationREST extends AbstractREST {
public static final String API_VERSION = "1.0";
@Inject
ApplicationSettingsService applicationSettingsService;
@GET
@ApiOperation(value = "Returns list of all available api endpoints", responseClass = "List[DocumentationEndPoint]")
public Response getAllApis(@Context Application app) {
TypeUtil.addAllowablePackage(Entries.class.getPackage().getName());
TypeUtil.addAllowablePackage(MarkRequest.class.getPackage().getName());
Documentation doc = new Documentation();
for (Class<?> resource : app.getClasses()) {
if (ApiDocumentationREST.class.equals(resource)) {
continue;
}
Api api = resource.getAnnotation(Api.class);
if (api != null) {
doc.addApi(new DocumentationEndPoint(api.value(), api.description()));
}
}
doc.setSwaggerVersion(SwaggerSpec.version());
doc.setBasePath(getBasePath(applicationSettingsService.get().getPublicUrl()));
doc.setApiVersion(API_VERSION);
return Response.ok().entity(doc).build();
}
public static String getBasePath(String publicUrl) {
if (!publicUrl.endsWith("/")) {
publicUrl = publicUrl + "/";
}
publicUrl += "rest";
return publicUrl;
}
}

View File

@@ -33,6 +33,7 @@ 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.ReadingOrder;
import com.commafeed.backend.services.ApplicationSettingsService;
import com.commafeed.backend.services.FeedEntryService;
import com.commafeed.backend.services.FeedSubscriptionService;
import com.commafeed.frontend.SecurityCheck;
@@ -59,7 +60,7 @@ import com.wordnik.swagger.annotations.ApiParam;
@Path("/category")
@Api(value = "/category", description = "Operations about user categories")
public class CategoryREST extends AbstractResourceREST {
public class CategoryREST extends AbstractREST {
private static Logger log = LoggerFactory.getLogger(CategoryREST.class);
@@ -83,6 +84,9 @@ public class CategoryREST extends AbstractResourceREST {
@Inject
CacheService cache;
@Inject
ApplicationSettingsService applicationSettingsService;
@Path("/entries")
@GET

View File

@@ -20,6 +20,7 @@ import com.commafeed.backend.dao.FeedSubscriptionDAO;
import com.commafeed.backend.model.FeedEntryStatus;
import com.commafeed.backend.model.FeedSubscription;
import com.commafeed.backend.model.UserSettings.ReadingOrder;
import com.commafeed.backend.services.ApplicationSettingsService;
import com.commafeed.backend.services.FeedEntryService;
import com.commafeed.frontend.model.Entries;
import com.commafeed.frontend.model.Entry;
@@ -33,7 +34,7 @@ import com.wordnik.swagger.annotations.ApiParam;
@Path("/entry")
@Api(value = "/entry", description = "Operations about feed entries")
public class EntryREST extends AbstractResourceREST {
public class EntryREST extends AbstractREST {
@Inject
FeedEntryService feedEntryService;
@@ -43,6 +44,9 @@ public class EntryREST extends AbstractResourceREST {
@Inject
FeedSubscriptionDAO feedSubscriptionDAO;
@Inject
ApplicationSettingsService applicationSettingsService;
@Path("/mark")
@POST

View File

@@ -55,6 +55,7 @@ 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.ReadingOrder;
import com.commafeed.backend.services.ApplicationSettingsService;
import com.commafeed.backend.services.FeedEntryService;
import com.commafeed.backend.services.FeedSubscriptionService;
import com.commafeed.frontend.SecurityCheck;
@@ -82,7 +83,7 @@ import com.wordnik.swagger.annotations.ApiParam;
@Path("/feed")
@Api(value = "/feed", description = "Operations about feeds")
public class FeedREST extends AbstractResourceREST {
public class FeedREST extends AbstractREST {
private static Logger log = LoggerFactory.getLogger(FeedREST.class);
@@ -124,6 +125,9 @@ public class FeedREST extends AbstractResourceREST {
@Context
private HttpServletRequest request;
@Inject
ApplicationSettingsService applicationSettingsService;
@Path("/entries")
@GET

View File

@@ -28,16 +28,18 @@ import com.commafeed.backend.feeds.FeedParser;
import com.commafeed.backend.feeds.FeedRefreshTaskGiver;
import com.commafeed.backend.feeds.FetchedFeed;
import com.commafeed.backend.model.Feed;
import com.commafeed.backend.model.UserRole.Role;
import com.commafeed.backend.services.ApplicationSettingsService;
import com.google.api.client.repackaged.com.google.common.base.Preconditions;
import com.commafeed.frontend.SecurityCheck;
import com.google.common.base.Preconditions;
@Path("/push")
public class PubSubHubbubCallbackREST {
public class PubSubHubbubCallbackREST extends AbstractREST {
private static Logger log = LoggerFactory.getLogger(PubSubHubbubCallbackREST.class);
@Context
HttpServletRequest request;
private HttpServletRequest request;
@Inject
FeedDAO feedDAO;
@@ -57,6 +59,7 @@ public class PubSubHubbubCallbackREST {
@Path("/callback")
@GET
@Produces(MediaType.TEXT_PLAIN)
@SecurityCheck(Role.NONE)
public Response verify(@QueryParam("hub.mode") String mode, @QueryParam("hub.topic") String topic,
@QueryParam("hub.challenge") String challenge, @QueryParam("hub.lease_seconds") String leaseSeconds,
@QueryParam("hub.verify_token") String verifyToken) {
@@ -87,6 +90,7 @@ public class PubSubHubbubCallbackREST {
@Path("/callback")
@POST
@Consumes({ MediaType.APPLICATION_ATOM_XML, "application/rss+xml" })
@SecurityCheck(Role.NONE)
public Response callback() {
if (!applicationSettingsService.get().isPubsubhubbub()) {

View File

@@ -13,19 +13,23 @@ import com.commafeed.backend.HttpGetter.HttpResult;
import com.commafeed.backend.StartupBean;
import com.commafeed.backend.feeds.FeedUtils;
import com.commafeed.backend.services.ApplicationPropertiesService;
import com.commafeed.backend.services.ApplicationSettingsService;
import com.commafeed.frontend.model.ServerInfo;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
@Path("/server")
@Api(value = "/server", description = "Operations about server infos")
public class ServerREST extends AbstractResourceREST {
public class ServerREST extends AbstractREST {
@Inject
StartupBean startupBean;
@Inject
HttpGetter httpGetter;
@Inject
ApplicationSettingsService applicationSettingsService;
@Path("/get")
@GET

View File

@@ -37,7 +37,7 @@ import com.wordnik.swagger.annotations.ApiParam;
@Path("/user")
@Api(value = "/user", description = "Operations about the user")
public class UserREST extends AbstractResourceREST {
public class UserREST extends AbstractREST {
@Inject
UserDAO userDAO;

View File

@@ -1,58 +0,0 @@
package com.commafeed.frontend.utils;
import org.apache.wicket.model.PropertyModel;
import ch.lambdaj.Lambda;
import ch.lambdaj.function.argument.Argument;
import ch.lambdaj.function.argument.ArgumentsFactory;
/**
* Utility class to generate PropertyModels in a type-safe way
*
*/
public class ModelFactory {
public static <T> String invokedProperty(T proxiedValue) {
Argument<T> a = ArgumentsFactory.actualArgument(proxiedValue);
return a.getInkvokedPropertyName();
}
public static <T> PropertyModel<T> model(Object value, T proxiedValue) {
String invokedPN = invokedProperty(proxiedValue);
PropertyModel<T> m = new PropertyModel<T>(value, invokedPN);
return m;
}
@SuppressWarnings("unchecked")
public static <T> T proxy(T t) {
Object object = Lambda.on(t.getClass());
return (T) object;
}
public static <T> T proxy(Class<T> clazz) {
return Lambda.on(clazz);
}
/**
* shortcuts to ModelFactory
*
*/
public static class MF {
public static <T> String i(T proxiedValue) {
return ModelFactory.invokedProperty(proxiedValue);
}
public static <T> PropertyModel<T> m(Object value, T proxiedValue) {
return ModelFactory.model(value, proxiedValue);
}
public static <T> T p(T t) {
return ModelFactory.proxy(t);
}
public static <T> T p(Class<T> clazz) {
return ModelFactory.proxy(clazz);
}
}
}

View File

@@ -0,0 +1,57 @@
import java.io.File;
import org.apache.commons.io.FileUtils;
import com.commafeed.frontend.model.Entries;
import com.commafeed.frontend.model.request.MarkRequest;
import com.commafeed.frontend.rest.RESTApplication;
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;
public class SwaggerStaticGenerator {
public void generate(String directory) throws Exception {
JaxrsApiReader.setFormatString("");
TypeUtil.addAllowablePackage(Entries.class.getPackage().getName());
TypeUtil.addAllowablePackage(MarkRequest.class.getPackage().getName());
RESTApplication app = new RESTApplication();
String apiVersion = "1.0";
String swaggerVersion = SwaggerSpec.version();
String basePath = "../rest";
Documentation doc = new Documentation();
for (Class<?> resource : app.getClasses()) {
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);
apiDoc.setSwaggerVersion(swaggerVersion);
apiDoc.setApiVersion(apiVersion);
write(apiDoc, directory);
doc.addApi(new DocumentationEndPoint(api.value(), api.description()));
}
}
doc.setSwaggerVersion(swaggerVersion);
doc.setApiVersion(apiVersion);
write(doc, directory);
}
private static void write(Documentation doc, String directory) throws Exception {
FileUtils.writeStringToFile(new File(directory, doc.getResourcePath() == null ? "resources" : doc.getResourcePath()), new ObjectMapper().writeValueAsString(doc));
}
}

View File

@@ -25,7 +25,7 @@
}
url = url.substring(0, url.length - 1);
url = url.substring(0, url.lastIndexOf('/'));
url = url + '/rest/resources';
url = url + '/api/swagger-doc/resources';
window.swaggerUi = new SwaggerUi({
discoveryUrl:url,
apiKey:"",