Java tutorial
//============================================================================= //=== Copyright (C) 2001-2007 Food and Agriculture Organization of the //=== United Nations (FAO-UN), United Nations World Food Programme (WFP) //=== and United Nations Environment Programme (UNEP) //=== //=== This program is free software; you can redistribute it and/or modify //=== it under the terms of the GNU General Public License as published by //=== the Free Software Foundation; either version 2 of the License, or (at //=== your option) any later version. //=== //=== This program is distributed in the hope that it will be useful, but //=== WITHOUT ANY WARRANTY; without even the implied warranty of //=== MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //=== General Public License for more details. //=== //=== You should have received a copy of the GNU General Public License //=== along with this program; if not, write to the Free Software //=== Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA //=== //=== Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2, //=== Rome - Italy. email: geonetwork@osgeo.org //============================================================================== package org.fao.geonet.services.main; import jeeves.constants.Jeeves; import jeeves.exceptions.BadParameterEx; import jeeves.interfaces.Service; import jeeves.resources.dbms.Dbms; import jeeves.server.ProfileManager; import jeeves.server.ServiceConfig; import jeeves.server.UserSession; import jeeves.server.context.ServiceContext; import jeeves.server.overrides.ConfigurationOverrides; import jeeves.utils.Xml; import org.fao.geonet.GeonetContext; import org.fao.geonet.constants.Edit; import org.fao.geonet.constants.Geonet; import org.fao.geonet.kernel.SchemaManager; import org.fao.geonet.kernel.search.MetaSearcher; import org.fao.geonet.kernel.search.SearchManager; import org.fao.geonet.kernel.security.GeonetworkUser; import org.fao.geonet.kernel.setting.SettingManager; import org.fao.geonet.lib.Lib; import org.fao.geonet.services.region.RegionsDAO; import org.fao.geonet.services.util.z3950.RepositoryInfo; import org.jdom.Element; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; public class Info implements Service { private static final String READ_ONLY = "readonly"; private static final String INDEX = "index"; private String xslPath; private String appPath; private String xmlPath; private String webInfPath; private String otherSheets; private ServiceConfig _config; //-------------------------------------------------------------------------- //--- //--- Init //--- //-------------------------------------------------------------------------- public void init(String appPath, ServiceConfig config) throws Exception { this.appPath = appPath; xslPath = appPath + Geonet.Path.STYLESHEETS + "/xml"; otherSheets = appPath + Geonet.Path.STYLESHEETS; xmlPath = appPath + Geonet.Path.XML; webInfPath = appPath + "/WEB-INF"; _config = config; } //-------------------------------------------------------------------------- //--- //--- Service //--- //-------------------------------------------------------------------------- public Element exec(Element inParams, ServiceContext context) throws Exception { GeonetContext gc = (GeonetContext) context.getHandlerContext(Geonet.CONTEXT_NAME); SettingManager sm = gc.getSettingManager(); Dbms dbms = (Dbms) context.getResourceManager().open(Geonet.Res.MAIN_DB); Element params = (Element) inParams.clone(); // --- if we have a parameter specified in the config then use it instead // --- of the usual params String ptype = _config.getValue("type"); if (ptype != null) { params.removeContent(); params.addContent(new Element("type").setText(ptype)); } Element result = new Element("root"); for (Iterator i = params.getChildren("type").iterator(); i.hasNext();) { Element el = (Element) i.next(); String name = el.getName(); String type = el.getText(); if (type.equals("site")) { // adds all listed values in settings element result.addContent(sm.getValues(new String[] { SettingManager.SYSTEM_SITE_NAME_PATH, "system/site/organization", SettingManager.SYSTEM_SITE_SITE_ID_PATH, "system/platform/version", "system/platform/subVersion" })); } else if (type.equals("config")) { // Return a set of properties which define what // to display or not in the user interface Element configEl = new Element("config"); configEl.addContent(gc.getSettingManager().getAll()); result.addContent(configEl); Element natmap = null; try { String configPath = webInfPath + "/config-gui.xml"; Element gui = Xml.loadFile(configPath); ConfigurationOverrides.DEFAULT.updateWithOverrides(configPath, null, appPath, gui); natmap = Xml.selectElement(gui, "nationalmap"); } catch (Exception e) { e.printStackTrace(); } if (natmap != null) { result.addContent(natmap.detach()); } } else if (type.equals("inspire")) { result.addContent(gc.getSettingManager() .getValues(new String[] { "system/inspire/enableSearchPanel", "system/inspire/enable" })); } else if (type.equals("harvester")) { result.addContent( gc.getSettingManager().getValues(new String[] { "system/harvester/enableEditing" })); } else if (type.equals("userGroupOnly")) { result.addContent( gc.getSettingManager().getValues(new String[] { "system/metadataprivs/usergrouponly" })); } else if (type.equals("categories")) result.addContent(Lib.local.retrieve(dbms, "Categories")); else if (type.equals("groups")) { Element r = getGroups(context, dbms, params.getChildText("profile"), false); result.addContent(r); } else if (type.equals("groupsIncludingSystemGroups")) { Element r = getGroups(context, dbms, null, true); result.addContent(r); } else if (type.equals("operations")) result.addContent(Lib.local.retrieve(dbms, "Operations")); else if (type.equals("regions")) { RegionsDAO dao = context.getApplicationContext().getBean(RegionsDAO.class); Element regions = dao.createSearchRequest(context).xmlResult(); result.addContent(regions); } else if (type.equals("isolanguages")) result.addContent(Lib.local.retrieve(dbms, "IsoLanguages")); else if (type.equals("sources")) result.addContent(getSources(dbms, sm)); else if (type.equals("users")) result.addContent(getUsers(context, dbms)); else if (type.equals("templates")) result.addContent(getTemplates(context)); else if (type.equals("z3950repositories")) result.addContent(getZRepositories(context, sm)); else if (type.equals("me")) result.addContent(getMyInfo(context)); else if (type.equals("auth")) result.addContent(getAuth(context)); else if (type.equals(READ_ONLY)) result.addContent(getReadOnly(gc)); else if (type.equals(INDEX)) result.addContent(getIndex(gc)); else if (type.equals("schemas")) result.addContent(getSchemas(gc.getSchemamanager())); else if (type.equals("status")) result.addContent(Lib.local.retrieve(dbms, "StatusValues")); else throw new BadParameterEx("Unknown type parameter value.", type); } result.addContent(getEnv(context)); Element response = Xml.transform(result, xslPath + "/info.xsl"); return response; } /** * Returns whether GN is in indexing (true or false). * @param gc * @return */ private Element getIndex(GeonetContext gc) { Element isIndexing = new Element(INDEX); isIndexing.setText(Boolean.toString(gc.getDataManager().isIndexing())); return isIndexing; } /** * Returns whether GN is in read-only mode (true or false). * @param gc * @return */ private Element getReadOnly(GeonetContext gc) { Element readOnly = new Element(READ_ONLY); readOnly.setText(Boolean.toString(gc.isReadOnly())); return readOnly; } private Element getAuth(ServiceContext context) { Element auth = new Element("auth"); Element cas = new Element("casEnabled").setText(Boolean.toString(ProfileManager.isCasEnabled())); auth.addContent(cas); return auth; } //-------------------------------------------------------------------------- //--- //--- Private methods //--- //-------------------------------------------------------------------------- private Element getMyInfo(ServiceContext context) { Element data = new Element("me"); UserSession userSession = context.getUserSession(); if (userSession.isAuthenticated()) { data.setAttribute("authenticated", "true"); data.addContent(new Element(Geonet.Elem.PROFILE).setText(userSession.getProfile())) .addContent(new Element(GeonetworkUser.USERNAME_COLUMN).setText(userSession.getUsername())) .addContent(new Element(Geonet.Elem.ID).setText(userSession.getUserId())) .addContent(new Element(Geonet.Elem.NAME).setText(userSession.getName())) .addContent(new Element(Geonet.Elem.SURNAME).setText(userSession.getSurname())) .addContent(new Element(Geonet.Elem.EMAIL).setText(userSession.getEmailAddr())) .addContent(new Element(Geonet.Elem.HASH).setText( org.apache.commons.codec.digest.DigestUtils.md5Hex(userSession.getEmailAddr()))); } else { data.setAttribute("authenticated", "false"); } return data; } private Element getSchemas(SchemaManager schemaMan) throws Exception { Element response = new Element("schemas"); for (String schema : schemaMan.getSchemas()) { Element elem = new Element("schema").addContent(new Element("name").setText(schema)) .addContent(new Element("id").setText(schemaMan.getIdVersion(schema).one())) .addContent(new Element("version").setText(schemaMan.getIdVersion(schema).two())) .addContent(new Element("description").setText(schema)) .addContent(new Element("namespaces").setText(schemaMan.getNamespaceString(schema))); // is it editable? if (schemaMan.getSchema(schema).canEdit()) { elem.addContent(new Element("edit").setText("true")); } else { elem.addContent(new Element("edit").setText("false")); } // get the conversion information and add it too List<Element> convElems = schemaMan.getConversionElements(schema); if (convElems.size() > 0) { Element conv = new Element("conversions"); conv.addContent(convElems); elem.addContent(conv); } response.addContent(elem); } return response; } //-------------------------------------------------------------------------- /** * Retrieves a user's groups. * * @param context * @param dbms * @param profile * @param includingSystemGroups if true, also returns the system groups ('GUEST', 'intranet', 'all') * @return * @throws SQLException */ private Element getGroups(ServiceContext context, Dbms dbms, String profile, boolean includingSystemGroups) throws SQLException { UserSession session = context.getUserSession(); if (!session.isAuthenticated()) { return Lib.local.retrieveWhereOrderBy(dbms, "Groups", "id < ?", "id", 2); } Element result; // you're Administrator if (Geonet.Profile.ADMINISTRATOR.equals(session.getProfile())) { // return all groups result = Lib.local.retrieveWhereOrderBy(dbms, "Groups", null, "id"); } // you're no Administrator else { // retrieve your groups Element list; if (profile == null) { String query = "SELECT groupId AS id FROM UserGroups WHERE userId=?"; list = dbms.select(query, session.getUserIdAsInt()); } else { String query = "SELECT groupId AS id FROM UserGroups WHERE userId=? and profile=?"; list = dbms.select(query, session.getUserIdAsInt(), profile); } Set<String> ids = Lib.element.getIds(list); // include system groups if requested (used in harvesters) if (includingSystemGroups) { // these DB keys of system groups are hardcoded ! ids.add("-1"); ids.add("0"); ids.add("1"); } // retrieve all groups Element groups = Lib.local.retrieveWhereOrderBy(dbms, "Groups", null, "id"); // filter all groups so only your groups (+ maybe system groups) are retained result = Lib.element.pruneChildren(groups, ids); } return result; } //-------------------------------------------------------------------------- private Element getSources(Dbms dbms, SettingManager sm) throws SQLException { String query = "SELECT * FROM Sources ORDER BY name"; Element sources = new Element("sources"); String siteId = sm.getValue("system/site/siteId"); String siteName = sm.getValue("system/site/name"); add(sources, siteId, siteName); for (Object o : dbms.select(query).getChildren()) { Element rec = (Element) o; String uuid = rec.getChildText("uuid"); String name = rec.getChildText("name"); add(sources, uuid, name); } return sources; } //-------------------------------------------------------------------------- //--- ZRepositories //-------------------------------------------------------------------------- public Element getZRepositories(ServiceContext context, SettingManager sm) throws Exception { boolean z3950Enable = sm.getValue("system/z3950/enable").equals("true"); List<RepositoryInfo> repoList = new ArrayList<RepositoryInfo>(RepositoryInfo.getRepositories(context)); Element response = new Element("z3950repositories"); for (RepositoryInfo repo : repoList) { if (!z3950Enable && repo.getClassName().startsWith("org.fao.geonet")) { continue; // skip Local GeoNetwork Z server if not enabled } else { response.addContent( buildRecord(repo.getDn(), repo.getName(), repo.getCode(), repo.getServerCode())); } } return response; } //-------------------------------------------------------------------------- //--- Templates //-------------------------------------------------------------------------- private Element getTemplates(ServiceContext context) throws Exception { String styleSheet = otherSheets + "/portal-present.xsl"; Element result = search(context).setName(Jeeves.Elem.RESPONSE); Element root = new Element("root"); root.addContent(result); List list = Xml.transform(root, styleSheet).getChildren(); Element response = new Element("templates"); for (int i = 0; i < list.size(); i++) { Element elem = (Element) list.get(i); Element info = elem.getChild(Edit.RootChild.INFO, Edit.NAMESPACE); if (!elem.getName().equals("metadata")) continue; String id = info.getChildText(Edit.Info.Elem.ID); String template = info.getChildText(Edit.Info.Elem.IS_TEMPLATE); String schema = info.getChildText(Edit.Info.Elem.SCHEMA); if (template.equals("y")) response.addContent(buildTemplateRecord(id, elem.getChildText("title"), schema)); } return response; } //-------------------------------------------------------------------------- private Element search(ServiceContext context) throws Exception { GeonetContext gc = (GeonetContext) context.getHandlerContext(Geonet.CONTEXT_NAME); context.info("Creating searcher"); Element params = buildParams(); ServiceConfig config = new ServiceConfig(); SearchManager searchMan = gc.getSearchmanager(); MetaSearcher searcher = searchMan.newSearcher(SearchManager.LUCENE, Geonet.File.SEARCH_LUCENE); searcher.search(context, params, config); params.addContent(new Element("from").setText("1")); params.addContent(new Element("to").setText(searcher.getSize() + "")); Element result = searcher.present(context, params, config); searcher.close(); return result; } //-------------------------------------------------------------------------- private Element buildParams() { Element params = new Element(Jeeves.Elem.REQUEST); String arParams[] = { "extended", "off", "remote", "off", "attrset", "geo", "template", "y", "any", "", }; for (int i = 0; i < arParams.length / 2; i++) params.addContent(new Element(arParams[i * 2]).setText(arParams[i * 2 + 1])); return params; } //-------------------------------------------------------------------------- private Element buildRecord(String id, String name) { return buildRecord(id, name, null, null); } //-------------------------------------------------------------------------- private Element buildTemplateRecord(String id, String title, String schema) { return buildRecord(id, title, schema, null); } //-------------------------------------------------------------------------- private Element buildRecord(String id, String name, String code, String serverCode) { Element el = new Element("record"); Element idE = new Element("id").setText(id); if (code != null) idE.setAttribute("code", code); if (serverCode != null) idE.setAttribute("serverCode", serverCode); el.addContent(idE); el.addContent(new Element("name").setText(name)); return el; } //-------------------------------------------------------------------------- //--- Users //-------------------------------------------------------------------------- private Element getUsers(ServiceContext context, Dbms dbms) throws SQLException { UserSession us = context.getUserSession(); List list = getUsers(context, us, dbms); Element users = new Element("users"); for (Object o : list) { Element user = (Element) o; user = (Element) user.clone(); user.removeChild("password"); user.setName("user"); users.addContent(user); } return users; } //-------------------------------------------------------------------------- private List getUsers(ServiceContext context, UserSession us, Dbms dbms) throws SQLException { if (!us.isAuthenticated()) return new ArrayList<Element>(); int id = Integer.parseInt(us.getUserId()); if (us.getProfile().equals(Geonet.Profile.ADMINISTRATOR)) return dbms.select("SELECT * FROM Users").getChildren(); if (!us.getProfile().equals(Geonet.Profile.USER_ADMIN)) return dbms.select("SELECT * FROM Users WHERE id=?", id).getChildren(); //--- we have a user admin Set<String> hsMyGroups = getUserGroups(dbms, id); Set profileSet = context.getProfileManager().getProfilesSet(us.getProfile()); //--- retrieve all users Element elUsers = dbms.select("SELECT * FROM Users ORDER BY username"); //--- now filter them ArrayList<Element> alToRemove = new ArrayList<Element>(); for (Object o : elUsers.getChildren()) { Element elRec = (Element) o; String userId = elRec.getChildText("id"); String profile = elRec.getChildText("profile"); if (!profileSet.contains(profile)) alToRemove.add(elRec); else if (!hsMyGroups.containsAll(getUserGroups(dbms, Integer.parseInt(userId)))) alToRemove.add(elRec); } //--- remove unwanted users for (int i = 0; i < alToRemove.size(); i++) alToRemove.get(i).detach(); //--- return result return elUsers.getChildren(); } //-------------------------------------------------------------------------- private Set<String> getUserGroups(Dbms dbms, int id) throws SQLException { String query = "SELECT groupId AS id FROM UserGroups WHERE userId=?"; List list = dbms.select(query, id).getChildren(); HashSet<String> hs = new HashSet<String>(); for (int i = 0; i < list.size(); i++) { Element el = (Element) list.get(i); hs.add(el.getChildText("id")); } return hs; } //-------------------------------------------------------------------------- //--- //--- General purpose methods //--- //-------------------------------------------------------------------------- private void add(Element sources, String uuid, String name) { Element source = new Element("source").addContent(new Element("uuid").setText(uuid)) .addContent(new Element("name").setText(name)); sources.addContent(source); } //-------------------------------------------------------------------------- private Element getEnv(ServiceContext context) { return new Element("env").addContent(new Element("baseURL").setText(context.getBaseUrl())) .addContent(new Element("node").setText(context.getNodeId())); } }