Skip to content
Permalink
Browse files

Added support for Guice injection into SitemapMultiPageProvider objects.

  • Loading branch information...
jfendler committed May 8, 2016
1 parent 95cab1f commit 8e402cd3e8d6c61070caea5c0f5ce3ec550395df
@@ -20,7 +20,7 @@ Basic Usage:
<dependency>
<groupId>com.jensfendler</groupId>
<artifactId>ninja-sitemap</artifactId>
<version>0.0.2</version>
<version>0.0.3</version>
</dependency>

```
@@ -33,6 +33,12 @@ Basic Usage:
```

If you plan to use Guice injection in your `SitemapMultiPageProvider` classes (see `useInjector` setting below), you need to bind the respective classes here as well. E.g.
```java
bind( ProductSitemapMultiPageProvider.class );
```

- Inject `NinjaSitemapRoutes` into your `conf.Router` class, and make a call to its `init(Router)` method:

```java
@@ -65,24 +71,30 @@ Example:
@Singleton
public class MyContoller {
// create a single sitemap entry with default priority and change frequency
@Sitemap
public Result aboutUs(Context context) {
// ...
}
// create a single sitemap entry with maximum priority and an hourly change frequency
@Sitemap(priority=1.0, changeFrequency=Sitemap.HOURLY)
public Result homepage(Context context) {
// ...
}
// create a single sitemap entry with default priority and change frequency
@Sitemap
public Result aboutUs(Context context) {
// Create multiple entries in the sitemap for a controller method with `@PathParam` arguments
// A SimpleMultiPageProvider instance will be created straight from the given class (without Guice injection)
@Sitemap(multiPageProvider="modules.SimpleMultiPageProvider")
public Result productDetails(Context context, @PathParam("productId") long productId) {
// ...
}
// create multiple entries in the sitemap for a controller method with `@PathParam` arguments
@Sitemap(multiPageProvider="modules.MyMultiPageProvider")
// Create multiple entries in the sitemap for a controller method with `@PathParam` arguments
// A ProductSitemapMultiPageProvider instance will be created using the Guice injector, to allow e.g.
// injection of DAOs or other Ninja modules.
@Sitemap(multiPageProvider="modules.ProductSitemapMultiPageProvider", useInjector=true)
public Result productDetails(Context context, @PathParam("productId") long productId) {
// ...
}
@@ -92,9 +104,11 @@ public class MyContoller {

- You should now be able to view your sitemap by pointing your browser to `/sitemap.xml` (under your application's context path).

For further details, please have a look at the JavaDoc documentation, especially of the `Sitemap.java` annotation code.


Advanced Configuration
----------------------
Ninja Configuration Properties
------------------------------
Ninja Sitemap can be configured further with some properties in your `application.conf` file as follows:

- `ninja.sitemap.prefix` (String): The prefix URL to use for all entries in the sitemap. This property _should always_ be configured to ensure correct URLs in your sitemap. (See above).
@@ -82,6 +82,22 @@
*/
String multiPageProvider() default NO_MULTIPAGE_PROVIDER;

/**
* If set to true, instances of the {@link SitemapMultiPageProvider}
* specified in the {@link #multiPageProvider()} property will be created
* via the Guice injector (if possible). This will allow the created objects
* to access other DAOs or Ninja objects via Guice dependency injection.
*
* For this to work, the class specified in the {@link #multiPageProvider()}
* property must be bound in your <code>ninja.Module</code> class -
* preferably <em>before</em> the Ninja-Sitemap module is installed.
*
* @return true, if the Guice injector should be used to create instances of
* the {@link SitemapMultiPageProvider} class; or false (the
* default) for plain Java class instantiation.
*/
boolean useInjector() default false;

/**
* Explicitly provide a path for the sitemap entry of this controller
* method. Note: setting this parameter only makes sense for non-dynamic
@@ -24,6 +24,7 @@
import org.slf4j.LoggerFactory;

import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;
import com.jensfendler.ninjasitemap.SitemapRouteDetails;
import com.jensfendler.ninjasitemap.NinjaSitemapRoutes;
@@ -114,6 +115,9 @@
@Inject
protected SitemapRouteDetails sitemapDetailsProvider;

@Inject
protected Injector injector;

/**
* Returns the sitemap.xml data following a GET request to /sitemap.xml
*
@@ -194,26 +198,34 @@ private String createSitemap(Context context) {

// pinging search engines will take some time. run this in a new
// thread so that the current request can immediately be served.
Executors.defaultThreadFactory().newThread(new Runnable() {
public void run() {
if (shouldPingGoogle) {
try {
generator.pingGoogle(sitemapUrl);
LOG.info("Google search engine has been notified of updated sitemap at '{}'.", sitemapUrl);
} catch (GWTException e) {
LOG.warn("Failed to ping Google with updated sitemap.", e);
if (ninjaProperties.isProd()) {
// only ping search engines in PROD mode
Executors.defaultThreadFactory().newThread(new Runnable() {
public void run() {
if (shouldPingGoogle) {
try {
generator.pingGoogle(sitemapUrl);
LOG.info("Google search engine has been notified of updated sitemap at '{}'.",
sitemapUrl);
} catch (GWTException e) {
LOG.warn("Failed to ping Google with updated sitemap.", e);
}
}
}
if (shouldPingBing) {
try {
generator.pingBing(sitemapUrl);
LOG.info("Bing search engine has been notified of updated sitemap at '{}'.", sitemapUrl);
} catch (GWTException e) {
LOG.warn("Failed to ping Google with updated sitemap.", e);
if (shouldPingBing) {
try {
generator.pingBing(sitemapUrl);
LOG.info("Bing search engine has been notified of updated sitemap at '{}'.",
sitemapUrl);
} catch (GWTException e) {
LOG.warn("Failed to ping Google with updated sitemap.", e);
}
}
}
}
}).start();
}).start();
} else {
LOG.info("Not pinging search engines in non-production mode.");
}

}

// return the sitemap.xml data as a string
@@ -245,7 +257,9 @@ public void run() {
try {
Class<? extends SitemapMultiPageProvider> smppClass = (Class<? extends SitemapMultiPageProvider>) Class
.forName(smppClassName);
SitemapMultiPageProvider smpp = smppClass.newInstance();

SitemapMultiPageProvider smpp = sitemap.useInjector() ? injector.getInstance(smppClass)
: smppClass.newInstance();

if (!dynamicRoute && ninjaProperties.getBooleanWithDefault(KEY_SHOW_MPP_WARNINGS, true)) {
// using a MultiPageProvider for a non-dynamic route is
@@ -256,24 +270,35 @@ public void run() {
route.getControllerMethod().getName());
}

List<SitemapEntry> entries = smpp.getSitemapEntries(route, sitemap);
if ((entries == null) || (entries.size() == 0)) {
LOG.warn("{} did not return any sitemap entries for route {} to {}.{}.", smppClassName,
route.getUri(), route.getControllerClass().getName(),
route.getControllerMethod().getName());
} else {
for (SitemapEntry se : entries) {
WebPage wp = new WebPage();
wp.setName(se.getPagePath().replaceFirst("^/", ""));
wp.setShortName(se.getShortName());
wp.setShortDescription(se.getShortDescription());
wp.setLastMod(se.getLastModified());
wp.setPriority(se.getPriority());
wp.setChangeFreq(changeFrequencyFromInteger(se.getChangeFrequency()));

// add to the list of pages for this route
pages.add(wp);
try {
List<SitemapEntry> entries = smpp.getSitemapEntries(route, sitemap);
if ((entries == null) || (entries.size() == 0)) {
LOG.warn("{} did not return any sitemap entries for route {} to {}.{}.", smppClassName,
route.getUri(), route.getControllerClass().getName(),
route.getControllerMethod().getName());
} else {
for (SitemapEntry se : entries) {
WebPage wp = new WebPage();
wp.setName(se.getPagePath().replaceFirst("^/", ""));
wp.setShortName(se.getShortName());
wp.setShortDescription(se.getShortDescription());
wp.setLastMod(se.getLastModified());
wp.setPriority(se.getPriority());
wp.setChangeFreq(changeFrequencyFromInteger(se.getChangeFrequency()));

// add to the list of pages for this route
pages.add(wp);
}
}
} catch (NullPointerException npe) {
if (sitemap.useInjector()) {
// using injector - show an error message pointing to a
// likely cause of the problem.
LOG.error(
"NullPointerException in {} when using 'useInjector'. Perhaps you forgot to bind() your class in ninja.Module?",
smppClass.getName());
}
throw npe;
}

} catch (ClassNotFoundException e) {

0 comments on commit 8e402cd

Please sign in to comment.
You can’t perform that action at this time.