Hello, I have tried to create a dynamic sitemap generator using a servlet, I would like to help me by leaving your recommendations to optimize the code or a better way to achieve the creation of a dynamic sitemap.
The idea is to allow the author, to select whether or not the pages will appear on the sitemap, the way in which this is done will not be placed, but basically it will allow using the hideInSitemap fields, whose value will be true or false, in order to create the mapping.
class SitemapGenerator:
package es.hesperia.web.terrum.core.servlets;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.activation.UnsupportedDataTypeException;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.servlet.Servlet;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.servlets.HttpConstants;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.day.cq.search.PredicateGroup;
import com.day.cq.search.Query;
import com.day.cq.search.QueryBuilder;
import com.day.cq.search.result.Hit;
import com.day.cq.search.result.SearchResult;
@Component(service = Servlet.class, property = {
Constants.SERVICE_DESCRIPTION + "=Query Builder servlet",
"sling.servlet.methods=" + HttpConstants.METHOD_GET,
"sling.servlet.paths=" + "/bin/projectSitemap"
})
public class SitemapGenerator extends SlingSafeMethodsServlet {
final String path = "/content/project/language-master";
final String project = "/content/project";
final String propertyFilterVar = "hideInSitemap"; //field to search
final String propertyFilterValue = "false";
final String lastModified = "cq:lastModified";//last change to the page
final String priorityPage= "priorityPage";
private static final long serialVersionUID = 2610051404257637265L;
private static final Logger log = LoggerFactory.getLogger(SitemapGenerator.class);
@Reference
private transient QueryBuilder builder;
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) {
Session session = null;
try {
log.debug("----------< Executing Query Builder Servlet >----------");
ResourceResolver resourceResolver = request.getResourceResolver();
session = resourceResolver.adaptTo(Session.class);
Map<String, String> pages = new HashMap<>();
pages.put("path", this.path);
pages.put("property", this.propertyFilterVar);
pages.put("property.1_value", this.propertyFilterValue);
Query query = this.builder.createQuery(PredicateGroup.create(pages), session);
query.setHitsPerPage(-1);//unlimited results
String lastKey = "";
SearchResult searchResult = query.getResult();
PrintWriter out = response.getWriter();
List<List<String[]>> languageKey = new ArrayList<>();//list of pages by language
List<String[]> pagesList = null;//by pages
for(Hit hit : searchResult.getHits()) {
String[] contentNode = new String[4];
String pathUrl = hit.getPath();
String simplePath = pathUrl;
simplePath = simplePath.replaceAll(project, request.getServerName());
simplePath = simplePath.replaceAll("/jcr:content", ".html");
Resource rs = resourceResolver.getResource(pathUrl);//Metadata
Node node = rs.adaptTo(Node.class);
String actualKey = node.getAncestor(4).getPath();//arbol hasta el nivel del idioma
contentNode[0] = simplePath;//
url of the page
contentNode[1] = node.getProperty(lastModified).getString();//last update
contentNode[2] = node.getProperty(priorityPage).getString();//priority
contentNode[3] = actualKey.replace(this.path+"/", "");//format language -> [a-z]{2}
/**
* if lastKey is equal to actualKey, a new list of pages is added
* for a new language nueva
*/
if (!lastKey.equals(actualKey)) {
/**
* when lastKey is igual to "" is the first language that is stored
* and only the page list for the first language is initialized
*/
if (!lastKey.equals("")) {
languageKey.add(pagesList);
}
pagesList = new ArrayList<>();
lastKey = actualKey;
}
int size = pagesList.size();
Boolean inserted = false;
int index = 0;
/**
* alphabetically sorts each page, as it is added
*/
while (!inserted && index<size) {
if (simplePath.compareTo(pagesList.get(index)[0])<0) {
pagesList.add(index,contentNode);
inserted = true;
}
index++;
}
/**
* if no elements were inserted into the list, it is inserted at the end of the list
*/
if (!inserted) {
pagesList.add(contentNode);
}
}
languageKey.add(pagesList);
int numPages = languageKey.get(0).size();
int numLanguages = languageKey.size();
response.setContentType("text/xml");
out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
out.println("<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\" xmlns:xhtml=\"http://www.w3.org/1999/xhtml\">");
for (int i = 0; i < numPages; i++) {
out.println("<url>");
out.println("<loc>"+languageKey.get(numLanguages-1).get(i)[0]+"</loc>");//URL
/**
* if there is more than one language the alternative links are printed
* for each language
*/
if (numLanguages > 1) {
int size = numLanguages;
for (int index = size-1; index>=0;index--) {
out.println("<xhtml rel=\"alternate\" hreflang=\""+languageKey.get(index).get(i)[3]//language
+"\" href=\""+languageKey.get(index).get(i)[0]+"\" />");//url
}
}
String dateStr = languageKey.get(0).get(i)[1];//updated date
String pattern = "\\D\\d{3}"; //new format
dateStr = dateStr.replaceFirst(pattern, "");
out.println("<lastmod>"+dateStr+"</lastmod>");//last update
out.println("<priority>"+languageKey.get(0).get(i)[2]+"</priority>");//priority
out.println("</url>");
}
out.println("</urlset>");
session.save();
} catch (UnsupportedEncodingException|UnsupportedDataTypeException e) {
log.error("UnsupportedEncodingException|UnsupportedDataTypeException:", e);
} catch (IOException e) {
log.error("IOException:", e);
e.printStackTrace();
} catch (RepositoryException e) {
log.error("RepositoryException:", e);
e.printStackTrace();
} finally {
if(session != null) {
session.logout();
}
}
}
}
This is my code, it is personalized but I would like to know other points of view to improve it or other ways of doing it.
Solved! Go to Solution.
Views
Replies
Total Likes
Use Acs commons sitemap generator with simple configuration instead of developing custom logic..
Use Acs commons sitemap generator with simple configuration instead of developing custom logic..
Could you please share the steps for Using Acs commons sitemap generator with simple configuration instead of developing custom logic for change frequency.
Views
Replies
Total Likes