package org.wikipedia.miner.web.service; import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import org.simpleframework.xml.Attribute; import org.simpleframework.xml.ElementList; import org.wikipedia.miner.model.Article; import org.wikipedia.miner.model.Category; import org.wikipedia.miner.model.Wikipedia; import org.wikipedia.miner.web.service.ExploreArticleService.Page; import org.wikipedia.miner.web.util.UtilityMessages.*; import org.dmilne.xjsf.Service; import org.dmilne.xjsf.param.BooleanParameter; import org.dmilne.xjsf.param.IntParameter; import org.dmilne.xjsf.param.ParameterGroup; import org.dmilne.xjsf.param.StringParameter; import org.dmilne.xjsf.UtilityMessages.*; import com.google.gson.annotations.Expose; import org.dmilne.xjsf.param.IntListParameter; @SuppressWarnings("serial") public class ExploreCategoryService extends WMService { private enum GroupName { id, title, ids }; private ParameterGroup grpId; private IntParameter prmId; private ParameterGroup grpIds; private IntListParameter prmIds; private ParameterGroup grpTitle; private StringParameter prmTitle; private BooleanParameter prmParentCategories; private BooleanParameter prmChildCategories; private IntParameter prmChildCategoryMax; private IntParameter prmChildCategoryStart; private BooleanParameter prmChildArticles; private IntParameter prmChildArticleMax; private IntParameter prmChildArticleStart; public ExploreCategoryService() { super("core", "Provides details of individual categories", "<p></p>", false ); } @Override public void init(ServletConfig config) throws ServletException { super.init(config); grpId = new ParameterGroup(GroupName.id.name(), "To retrieve a category by id"); prmId = new IntParameter("id", "The unique identifier of the category to explore", null); grpId.addParameter(prmId); addParameterGroup(grpId); grpIds = new ParameterGroup(ExploreCategoryService.GroupName.ids.name(), "To retrieve categories by id"); prmIds = new IntListParameter("ids", "The list of unique identifiers for the articles to explore", null); grpIds.addParameter(prmIds); addParameterGroup(grpIds); grpTitle = new ParameterGroup(GroupName.title.name(), "To retrieve category by title"); prmTitle = new StringParameter("title", "The (case sensitive) title of the category to explore", null); grpTitle.addParameter(prmTitle); addParameterGroup(grpTitle); prmParentCategories = new BooleanParameter("parentCategories", "<b>true</b> if parent categories of this category should be returned, otherwise <b>false</b>", false); addGlobalParameter(prmParentCategories); prmChildCategories = new BooleanParameter("childCategories", "<b>true</b> if child categories of this category should be returned, otherwise <b>false</b>", false); addGlobalParameter(prmChildCategories); prmChildCategoryMax = new IntParameter("childCategoryMax", "the maximum number of child categories that should be returned. A max of <b>0</b> will result in all child categories being returned", 250); addGlobalParameter(prmChildCategoryMax); prmChildCategoryStart = new IntParameter("childCategoryStart", "the index of the first child category to return. Combined with <b>childCategoryMax</b>, this parameter allows the user to page through large lists of child categories", 0); addGlobalParameter(prmChildCategoryStart); prmChildArticles = new BooleanParameter("childArticles", "<b>true</b> if child articles of this category should be returned, otherwise <b>false</b>", false); addGlobalParameter(prmChildArticles); prmChildArticleMax = new IntParameter("childArticleMax", "the maximum number of child articles that should be returned. A max of <b>0</b> will result in all child articles being returned", 250); addGlobalParameter(prmChildArticleMax); prmChildArticleStart = new IntParameter("childArticleStart", "the index of the first child article to return. Combined with <b>childArticleMax</b>, this parameter allows the user to page through large lists of child articles", 0); addGlobalParameter(prmChildArticleStart); } @Override public Service.Message buildWrappedResponse(HttpServletRequest request) throws Exception { Wikipedia wikipedia = getWikipedia(request); ParameterGroup grp = getSpecifiedParameterGroup(request); if (grp == null) { return new ParameterMissingMessage(request); } Category cat = null; List<Category> list = new ArrayList<Category>(); List<Integer> invalidlist = new ArrayList<Integer>(); List<Integer> nulllist = new ArrayList<Integer>(); switch (GroupName.valueOf(grp.getName())) { case id: Integer id = prmId.getValue(request); org.wikipedia.miner.model.Page page = wikipedia.getPageById(id); if (page == null) { nulllist.add(id); } switch (page.getType()) { case category: list.add((Category) page); break; default: invalidlist.add(id); } break; case title: String title = prmTitle.getValue(request); cat = wikipedia.getCategoryByTitle(title); if (cat == null) { return new InvalidTitleMessage(request, title); } else { list.add(cat); } break; case ids: Integer[] ids = prmIds.getValue(request); for (int i = 0; i < ids.length; i++) { Integer integer = ids[i]; org.wikipedia.miner.model.Page pageIds = wikipedia.getPageById(integer); if (pageIds == null) { nulllist.add(integer); } switch (pageIds.getType()) { case disambiguation: case category: list.add((Category) pageIds); break; default: if (pageIds.getType() == org.wikipedia.miner.model.Page.PageType.article) { invalidlist.add(integer); } else { nulllist.add(integer); } } } break; } Message msg = new Message(request, invalidlist, nulllist); for (Category catego : list) { CatMsg mes = new CatMsg(catego); if (prmParentCategories.getValue(request)) { Category[] parents = catego.getParentCategories(); mes.setTotalParentCategories(parents.length); for (Category parent : parents) { mes.addParentCategory(new Page(parent)); } } if (prmChildCategories.getValue(request)) { int start = prmChildCategoryStart.getValue(request); int max = prmChildCategoryMax.getValue(request); if (max <= 0) { max = Integer.MAX_VALUE; } else { max = max + start; } Category[] children = catego.getChildCategories(); mes.setTotalChildCategories(children.length); for (int i = start; i < max && i < children.length; i++) { mes.addChildCategory(new Page(children[i])); } } if (prmChildArticles.getValue(request)) { int start = prmChildArticleStart.getValue(request); int max = prmChildArticleMax.getValue(request); if (max <= 0) { max = Integer.MAX_VALUE; } else { max = max + start; } Article[] children = catego.getChildArticles(); mes.setTotalChildArticles(children.length); for (int i = start; i < max && i < children.length; i++) { mes.addChildArticle(new Page(children[i])); } } msg.addCategory(mes); } return msg; } public static class Message extends Service.Message { @Expose @ElementList(required = true, entry = "nullList") private List<Integer> nullList = null; @Expose @ElementList(required = true, entry = "invalidList") private List<Integer> invalidList = null; @Expose @ElementList(required = true, entry = "catList") private List<CatMsg> catList = null; private ArrayList<Page> childCategories = null; private Message(HttpServletRequest request, List<Integer> invalidList, List<Integer> nullList) { super(request); this.nullList = nullList; this.invalidList = invalidList; catList = new ArrayList<CatMsg>(); } private void addCategory(CatMsg mes) { catList.add(mes); } } public static class CatMsg { @Expose @Attribute private int id; @Expose @Attribute private String title; @Expose @ElementList(required = false, entry = "parentCategory") private ArrayList<Page> parentCategories = null; @Expose @Attribute(required = false) private Integer totalParentCategories; @Expose @ElementList(required = false, entry = "childCategory") private ArrayList<Page> childCategories = null; @Expose @Attribute(required = false) private Integer totalChildCategories; @Expose @ElementList(required = false, entry = "childArticle") private ArrayList<Page> childArticles = null; @Expose @Attribute(required = false) private Integer totalChildArticles; private CatMsg(Category cat) { this.id = cat.getId(); this.title = cat.getTitle(); } private void addParentCategory(Page p) { if (parentCategories == null) { parentCategories = new ArrayList<Page>(); } parentCategories.add(p); } private void setTotalParentCategories(int total) { totalParentCategories = total; } private void addChildCategory(Page p) { if (childCategories == null) { childCategories = new ArrayList<Page>(); } childCategories.add(p); } private void setTotalChildCategories(int total) { totalChildCategories = total; } private void addChildArticle(Page p) { if (childArticles == null) { childArticles = new ArrayList<Page>(); } childArticles.add(p); } private void setTotalChildArticles(int total) { totalChildArticles = total; } public int getId() { return id; } public String getTitle() { return title; } public List<Page> getParentCategories() { if (parentCategories == null) { return Collections.unmodifiableList(new ArrayList<Page>()); } return Collections.unmodifiableList(parentCategories); } public Integer getTotalParentCategories() { return totalParentCategories; } public List<Page> getChildCategories() { if (childCategories == null) { return Collections.unmodifiableList(new ArrayList<Page>()); } return Collections.unmodifiableList(childCategories); } public Integer getTotalChildCategories() { return totalChildCategories; } public List<Page> getChildArticles() { if (childArticles == null) { return Collections.unmodifiableList(new ArrayList<Page>()); } return Collections.unmodifiableList(childArticles); } public Integer getTotalChildArticles() { return totalChildArticles; } } }