0001: /**
0002: * Copyright 2004 Sun Microsystems, Inc. All
0003: * rights reserved. Use of this product is subject
0004: * to license terms. Federal Acquisitions:
0005: * Commercial Software -- Government Users
0006: * Subject to Standard License Terms and
0007: * Conditions.
0008: *
0009: * Sun, Sun Microsystems, the Sun logo, and Sun ONE
0010: * are trademarks or registered trademarks of Sun Microsystems,
0011: * Inc. in the United States and other countries.
0012: */package com.sun.portal.search.admin.mbeans;
0013:
0014: import java.io.*;
0015: import java.util.*;
0016: import java.util.logging.*;
0017:
0018: import javax.management.MBeanServer;
0019: import javax.management.MBeanServerConnection;
0020: import javax.management.ObjectName;
0021: import javax.management.remote.JMXConnector;
0022:
0023: import com.sun.portal.admin.server.PASModule;
0024: import com.sun.portal.admin.server.mbeans.PSResource;
0025: import com.sun.portal.admin.server.AdminServerUtil;
0026: import com.sun.portal.admin.common.context.PSConfigContext;
0027: import com.sun.portal.admin.common.context.PortalDomainContext;
0028: import com.sun.portal.admin.common.util.AdminUtil;
0029: import com.sun.portal.admin.common.PSMBeanException;
0030:
0031: import com.sun.portal.log.common.PortalLogger;
0032:
0033: import com.sun.portal.search.admin.util.DBUtil;
0034: import com.sun.portal.search.admin.mbeans.tasks.ClassConfig;
0035: import com.sun.portal.search.admin.mbeans.tasks.Rule;
0036:
0037: import com.sun.portal.search.rdm.RDMClassification;
0038: import com.sun.portal.search.rdm.RDMTaxonomy;
0039: import com.sun.portal.search.soif.*;
0040: import com.sun.portal.search.demo.Search;
0041: import com.sun.portal.util.Platform;
0042:
0043: public class Category extends PSResource implements CategoryMBean {
0044:
0045: private ObjectName objectName = null;
0046: private String host = null;
0047: private String configDir = null;
0048: private static Logger logger = PortalLogger
0049: .getLogger(Category.class);
0050:
0051: // Taxonomy config
0052: private RDMTaxonomy tax = null;
0053: private RDMClassification root = null;
0054: private boolean modified;
0055: private long lastModified;
0056: private Date lastActionDate;
0057: private String serverRoot = null;
0058: private String tax_conf_file = null;
0059: private Search search = null;
0060:
0061: public static String TAXONOMY_CONF = "taxonomy-description";
0062:
0063: // Classification Rule config
0064: private ClassConfig classConfig = null;
0065: private String class_conf_file = null;
0066: private long classLastModified;
0067:
0068: public static String CLASSIFICATION_CONF = "classification.conf";
0069: public static String classmethod[] = { "is", "contains",
0070: "begins with", "ends with", "regular" };
0071: public static String classmethod_string[] = { "by-exact",
0072: "by-substr", "by-prefix", "by-suffix", "by-regex" };
0073:
0074: public void init(PSConfigContext cc, PortalDomainContext pdc,
0075: List path) {
0076:
0077: super .init(cc, pdc, path);
0078:
0079: try {
0080: objectName = AdminUtil.getResourceMBeanObjectName(
0081: AdminUtil.SEARCH_CATEGORY_MBEAN_TYPE, path);
0082: host = pdc.getAttributeValue(
0083: AdminUtil.SEARCH_CATEGORY_MBEAN_TYPE, path, "Host");
0084: } catch (Exception e) {
0085: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
0086: }
0087:
0088: search = new Search();
0089:
0090: try {
0091: if (AdminUtil.isLocal(host)) {
0092: //get the SearchServer associated with the Category MBean
0093: MBeanServer ms = PASModule.getMBeanServer();
0094: LinkedList serverpath = new LinkedList();
0095: serverpath.addFirst(path.get(2));
0096: serverpath.addFirst(path.get(1));
0097: ObjectName searchServer = AdminUtil
0098: .getResourceMBeanObjectName(
0099: AdminUtil.SEARCHSERVER_MBEAN_TYPE,
0100: serverpath);
0101:
0102: serverRoot = (String) ms.getAttribute(searchServer,
0103: "SearchServerRoot");
0104: if (serverRoot == null) {
0105: Object tokens[] = { "Category.init(): failed to get search server root directory" };
0106: logger
0107: .log(Level.SEVERE, "PSSH_CSPSAMB0002",
0108: tokens);
0109: }
0110:
0111: configDir = (String) ms.getAttribute(searchServer,
0112: "ConfigDir");
0113: if (configDir == null) {
0114: Object tokens[] = { "Category.init(): failed to get search server config directory" };
0115: logger
0116: .log(Level.SEVERE, "PSSH_CSPSAMB0002",
0117: tokens);
0118: configDir = serverRoot + File.separator + "config";
0119: }
0120:
0121: //intialize classification rules
0122: class_conf_file = configDir + File.separator
0123: + CLASSIFICATION_CONF;
0124: classConfig = new ClassConfig(class_conf_file);
0125: setClassLastModified();
0126:
0127: //load taxonomy
0128: Object[] params = { TAXONOMY_CONF };
0129: String[] signature = { "java.lang.String" };
0130:
0131: tax_conf_file = (String) ms.invoke(searchServer,
0132: "getConfigValue", params, signature);
0133: if (tax_conf_file == null) {
0134: Object tokens[] = { "Category.init(): failed to get search server taxonomy file name" };
0135: logger
0136: .log(Level.SEVERE, "PSSH_CSPSAMB0002",
0137: tokens);
0138: } else {
0139: load();
0140: }
0141: }
0142: } catch (Exception e) {
0143: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
0144: }
0145: }
0146:
0147: /*
0148: * Methods to manage Classification Rules
0149: */
0150: public ArrayList listClassRules(String ruleID)
0151: throws PSMBeanException, java.net.UnknownHostException {
0152: if (!AdminUtil.isLocal(host)) {
0153: try {
0154: JMXConnector jmxc = AdminServerUtil
0155: .getJMXConnector(host);
0156: MBeanServerConnection msc = jmxc
0157: .getMBeanServerConnection();
0158: Object[] params = { ruleID };
0159: String[] signatures = { "java.lang.String" };
0160: ArrayList result = (ArrayList) msc.invoke(objectName,
0161: "listClassRules", params, signatures);
0162: jmxc.close();
0163: return result;
0164: } catch (Exception e) {
0165: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
0166: throw new PSMBeanException("Category:listClassRules", e
0167: .toString(), e);
0168: }
0169: } else {
0170:
0171: ArrayList classlist = new ArrayList();
0172: ArrayList rules = classConfig.getRulesList();
0173: int n = rules.size();
0174:
0175: if (ruleID == null || ruleID.equals("")) {
0176: for (int i = 0; i < n; i++) {
0177: Rule rule = (Rule) rules.get(i);
0178: HashMap rmap = new HashMap();
0179: rmap.put("Source", rule.getSrc());
0180: //rmap.put("Method", rule.getMethod());
0181: rmap
0182: .put("Method", getMethodLabel(rule
0183: .getMethod()));
0184: rmap.put("Criterion", rule.getName());
0185: rmap.put("Classification", rule.getAction());
0186: rmap.put("CaseSensitive", Boolean.valueOf(rule
0187: .isCaseSensitive()));
0188: classlist.add(rmap);
0189: }
0190:
0191: } else {
0192: int id = Integer.parseInt(ruleID);
0193: if (id < 0 || id > classConfig.getRulesList().size())
0194: return null;
0195: Rule rule = (Rule) rules.get(id);
0196: HashMap rmap = new HashMap();
0197: rmap.put("Source", rule.getSrc());
0198: //rmap.put("Method", rule.getMethod());
0199: rmap.put("Method", getMethodLabel(rule.getMethod()));
0200: rmap.put("Criterion", rule.getName());
0201: rmap.put("Classification", rule.getAction());
0202: rmap.put("CaseSensitive", Boolean.valueOf(rule
0203: .isCaseSensitive()));
0204: classlist.add(rmap);
0205: }
0206:
0207: return classlist;
0208: }
0209: }
0210:
0211: public Boolean createClassRule(String source, String method_label,
0212: String criterion, String category, Boolean isCase)
0213: throws PSMBeanException, java.net.UnknownHostException {
0214: if (!AdminUtil.isLocal(host)) {
0215: try {
0216: JMXConnector jmxc = AdminServerUtil
0217: .getJMXConnector(host);
0218: MBeanServerConnection msc = jmxc
0219: .getMBeanServerConnection();
0220: Object[] params = { source, method_label, criterion,
0221: category, isCase };
0222: String[] signatures = { "java.lang.String",
0223: "java.lang.String", "java.lang.String",
0224: "java.lang.String", "java.lang.Boolean" };
0225: Boolean result = (Boolean) msc.invoke(objectName,
0226: "createClassRule", params, signatures);
0227: jmxc.close();
0228: return result;
0229: } catch (Exception e) {
0230: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
0231: throw new PSMBeanException("Category:createClassRule",
0232: e.toString(), e);
0233: }
0234: } else {
0235:
0236: String method = getMethodString(method_label);
0237:
0238: if (classConfig
0239: .isExist(source, method, criterion, category)) {
0240: return Boolean.FALSE;
0241: }
0242:
0243: boolean iscase = isCase.booleanValue();
0244: if (classConfig.add(source, method, criterion, category,
0245: iscase)) {
0246: classConfig.save();
0247: setClassLastModified();
0248: return Boolean.TRUE;
0249: } else {
0250: return Boolean.FALSE;
0251: }
0252: }
0253:
0254: }
0255:
0256: public Boolean deleteClassRules(ArrayList ids)
0257: throws PSMBeanException, java.net.UnknownHostException {
0258: if (!AdminUtil.isLocal(host)) {
0259: try {
0260: JMXConnector jmxc = AdminServerUtil
0261: .getJMXConnector(host);
0262: MBeanServerConnection msc = jmxc
0263: .getMBeanServerConnection();
0264: Object[] params = { ids };
0265: String[] signatures = { "java.util.ArrayList" };
0266: Boolean result = (Boolean) msc.invoke(objectName,
0267: "deleteClassRules", params, signatures);
0268: jmxc.close();
0269: return result;
0270: } catch (Exception e) {
0271: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
0272: throw new PSMBeanException("Category:deleteClassRules",
0273: e.toString(), e);
0274: }
0275: } else {
0276: if (ids != null) {
0277: for (int i = ids.size() - 1; i >= 0; i--) {
0278: String ruleId = (String) ids.get(i);
0279: int id = Integer.parseInt(ruleId);
0280: if (id >= 0
0281: && id < classConfig.getRulesList().size())
0282: classConfig.delete(id);
0283: }
0284: classConfig.save();
0285: setClassLastModified();
0286: return Boolean.TRUE;
0287: }
0288: return Boolean.FALSE;
0289: }
0290: }
0291:
0292: public Boolean deleteClassRule(String ruleId)
0293: throws PSMBeanException, java.net.UnknownHostException {
0294: if (!AdminUtil.isLocal(host)) {
0295: try {
0296: JMXConnector jmxc = AdminServerUtil
0297: .getJMXConnector(host);
0298: MBeanServerConnection msc = jmxc
0299: .getMBeanServerConnection();
0300: Object[] params = { ruleId };
0301: String[] signatures = { "java.lang.String" };
0302: Boolean result = (Boolean) msc.invoke(objectName,
0303: "deleteClassRule", params, signatures);
0304: jmxc.close();
0305: return result;
0306: } catch (Exception e) {
0307: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
0308: throw new PSMBeanException("Category:deleteClassRule",
0309: e.toString(), e);
0310: }
0311: } else {
0312:
0313: int id = Integer.parseInt(ruleId);
0314: if (id < 0 || id > classConfig.getRulesList().size())
0315: return Boolean.FALSE;
0316:
0317: classConfig.delete(id);
0318: classConfig.save();
0319: setClassLastModified();
0320: return Boolean.TRUE;
0321: }
0322: }
0323:
0324: public Boolean editClassRule(String ruleId, String source,
0325: String method_label, String criterion, String category,
0326: Boolean isCase) throws PSMBeanException,
0327: java.net.UnknownHostException {
0328: if (!AdminUtil.isLocal(host)) {
0329: try {
0330: JMXConnector jmxc = AdminServerUtil
0331: .getJMXConnector(host);
0332: MBeanServerConnection msc = jmxc
0333: .getMBeanServerConnection();
0334: Object[] params = { ruleId, source, method_label,
0335: criterion, category, isCase };
0336: String[] signatures = { "java.lang.String",
0337: "java.lang.String", "java.lang.String",
0338: "java.lang.String", "java.lang.String",
0339: "java.lang.Boolean" };
0340: Boolean result = (Boolean) msc.invoke(objectName,
0341: "editClassRule", params, signatures);
0342: jmxc.close();
0343: return result;
0344: } catch (Exception e) {
0345: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
0346: throw new PSMBeanException("Category:editClassRule", e
0347: .toString(), e);
0348: }
0349: } else {
0350: int id = Integer.parseInt(ruleId);
0351:
0352: if (id < 0 || id > classConfig.getRulesList().size())
0353: return Boolean.FALSE;
0354:
0355: String method = getMethodString(method_label);
0356:
0357: if (classConfig.isExist(source, method, criterion,
0358: category, id)) {
0359: return Boolean.FALSE;
0360: }
0361:
0362: if (isCase == null)
0363: isCase = Boolean.TRUE;
0364:
0365: boolean iscase = isCase.booleanValue();
0366:
0367: classConfig.update(id, source, method, criterion, category,
0368: iscase);
0369: classConfig.save();
0370: setClassLastModified();
0371: return Boolean.TRUE;
0372: }
0373: }
0374:
0375: /*
0376: * if the classification.conf file is newer than the mbean's timestamp
0377: * reload the file and return true
0378: */
0379: public Boolean syncClassConfig() throws PSMBeanException,
0380: java.net.UnknownHostException {
0381: if (!AdminUtil.isLocal(host)) {
0382: try {
0383: JMXConnector jmxc = AdminServerUtil
0384: .getJMXConnector(host);
0385: MBeanServerConnection msc = jmxc
0386: .getMBeanServerConnection();
0387: Object[] params = {};
0388: String[] signatures = {};
0389: Boolean result = (Boolean) msc.invoke(objectName,
0390: "syncClassConfig", params, signatures);
0391: jmxc.close();
0392: return result;
0393: } catch (Exception e) {
0394: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
0395: return Boolean.FALSE;
0396: }
0397: } else {
0398: try {
0399: File f = new File(class_conf_file);
0400: if ((classLastModified != 0)
0401: && (classLastModified < f.lastModified())) {
0402: classConfig = new ClassConfig(class_conf_file);
0403: classLastModified = f.lastModified();
0404: return Boolean.TRUE;
0405: } else {
0406: return Boolean.FALSE;
0407: }
0408: } catch (Exception e) {
0409: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
0410: throw new PSMBeanException(
0411: "Failed to verify the current time stamp of the classification.conf file.",
0412: "Category.syncClassConfig()", e);
0413: }
0414: }
0415: }
0416:
0417: /*
0418: * return true if the classification rule has already existed
0419: */
0420:
0421: public Boolean existClassRule(String source, String method_label,
0422: String criterion, String category)
0423: throws java.net.UnknownHostException {
0424: if (!AdminUtil.isLocal(host)) {
0425: try {
0426: JMXConnector jmxc = AdminServerUtil
0427: .getJMXConnector(host);
0428: MBeanServerConnection msc = jmxc
0429: .getMBeanServerConnection();
0430: Object[] params = { source, method_label, criterion,
0431: category };
0432: String[] signatures = { "java.lang.String",
0433: "java.lang.String", "java.lang.String",
0434: "java.lang.String" };
0435: Boolean result = (Boolean) msc.invoke(objectName,
0436: "existClassRule", params, signatures);
0437: jmxc.close();
0438: return result;
0439: } catch (Exception e) {
0440: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
0441: return Boolean.FALSE;
0442: }
0443: } else {
0444: String method = getMethodString(method_label);
0445: if (classConfig
0446: .isExist(source, method, criterion, category)) {
0447: return Boolean.TRUE;
0448: } else {
0449: return Boolean.FALSE;
0450: }
0451: }
0452: }
0453:
0454: public Boolean existClassRule(String source, String method_label,
0455: String criterion, String category, String ruleID)
0456: throws java.net.UnknownHostException {
0457: if (!AdminUtil.isLocal(host)) {
0458: try {
0459: JMXConnector jmxc = AdminServerUtil
0460: .getJMXConnector(host);
0461: MBeanServerConnection msc = jmxc
0462: .getMBeanServerConnection();
0463: Object[] params = { source, method_label, criterion,
0464: category, ruleID };
0465: String[] signatures = { "java.lang.String",
0466: "java.lang.String", "java.lang.String",
0467: "java.lang.String", "java.lang.String" };
0468: Boolean result = (Boolean) msc.invoke(objectName,
0469: "existClassRule", params, signatures);
0470: jmxc.close();
0471: return result;
0472: } catch (Exception e) {
0473: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
0474: return Boolean.FALSE;
0475: }
0476: } else {
0477: int exceptindex = Integer.parseInt(ruleID);
0478: String method = getMethodString(method_label);
0479: if (classConfig.isExist(source, method, criterion,
0480: category, exceptindex)) {
0481: return Boolean.TRUE;
0482: } else {
0483: return Boolean.FALSE;
0484: }
0485: }
0486: }
0487:
0488: // Method to get the method string by method label of a rule
0489: public String getMethodString(String label) {
0490: int methodIndex = 0;
0491: for (int i = 0; i < classmethod.length; i++) {
0492: if (label.equalsIgnoreCase(classmethod[i])) {
0493: methodIndex = i;
0494: }
0495: }
0496: return classmethod_string[methodIndex];
0497: }
0498:
0499: public String getMethodLabel(String methodstring) {
0500: int methodIndex = 0;
0501: for (int i = 0; i < classmethod_string.length; i++) {
0502: if (methodstring.equalsIgnoreCase(classmethod_string[i])) {
0503: methodIndex = i;
0504: }
0505: }
0506: return classmethod[methodIndex];
0507: }
0508:
0509: private void setClassLastModified() throws PSMBeanException {
0510: try {
0511: File f = new File(class_conf_file);
0512: classLastModified = f.lastModified();
0513: } catch (Exception e) {
0514: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
0515: throw new PSMBeanException(
0516: "Failed to verify the current time stamp of the classification.conf file.",
0517: "Category.setClassLastModified()", e);
0518: }
0519: }
0520:
0521: /*
0522: * Methods to manage Taxonomy
0523: */
0524: public void load() {
0525: try {
0526: SOIFInputStream ss = new SOIFInputStream(tax_conf_file,
0527: "UTF-8");
0528: tax = new RDMTaxonomy(ss);
0529: if (tax == null) {
0530: root = null;
0531: Object tokens[] = { "Category.init(): failed to load taxonomy" };
0532: logger.log(Level.SEVERE, "PSSH_CSPSAMB0002", tokens);
0533: } else {
0534: root = tax.find(RDMTaxonomy.RDM_TAXONOMY_ROOT);
0535: if (root == null) {
0536: Object tokens[] = { "Category.init(): failed to find the root category in the taxonomy" };
0537: logger
0538: .log(Level.SEVERE, "PSSH_CSPSAMB0002",
0539: tokens);
0540: }
0541: setTimeStamp();
0542: }
0543: } catch (FileNotFoundException fnf) {
0544: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", fnf);
0545: } catch (UnsupportedEncodingException ue) {
0546: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", ue);
0547: } catch (SOIFException se) {
0548: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", se);
0549: } catch (Exception e) {
0550: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
0551: }
0552:
0553: }
0554:
0555: public RDMClassification retrieveTaxTreeRoot()
0556: throws PSMBeanException, java.net.UnknownHostException {
0557: if (!AdminUtil.isLocal(host)) {
0558: try {
0559: JMXConnector jmxc = AdminServerUtil
0560: .getJMXConnector(host);
0561: MBeanServerConnection msc = jmxc
0562: .getMBeanServerConnection();
0563: Object[] params = {};
0564: String[] signatures = {};
0565: RDMClassification result = (RDMClassification) msc
0566: .invoke(objectName, "retrieveTaxTreeRoot",
0567: params, signatures);
0568: jmxc.close();
0569: return result;
0570: } catch (Exception e) {
0571: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
0572: throw new PSMBeanException(
0573: "Category:retrieveTaxTreeRoot", e.toString(), e);
0574: }
0575: } else {
0576: return root;
0577: }
0578: }
0579:
0580: public RDMClassification getTaxTreeNode(String nodeID)
0581: throws PSMBeanException, java.net.UnknownHostException {
0582: if (!AdminUtil.isLocal(host)) {
0583: try {
0584: JMXConnector jmxc = AdminServerUtil
0585: .getJMXConnector(host);
0586: MBeanServerConnection msc = jmxc
0587: .getMBeanServerConnection();
0588: Object[] params = { nodeID };
0589: String[] signatures = { "java.lang.String" };
0590: RDMClassification result = (RDMClassification) msc
0591: .invoke(objectName, "getTaxTreeNode", params,
0592: signatures);
0593: jmxc.close();
0594: return result;
0595: } catch (Exception e) {
0596: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
0597: throw new PSMBeanException("Category:getTaxTreeNode", e
0598: .toString(), e);
0599: }
0600: } else {
0601: try {
0602: RDMClassification rc = tax.find(nodeID);
0603: return rc;
0604: } catch (Exception e) {
0605: //logger.logp(Level.SEVERE, "Category", "getTaxTreeNode()", "Exception- " + e.getMessage());
0606: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
0607: return null;
0608: }
0609: }
0610: }
0611:
0612: // get the top node of the tax tree
0613: public String retrieveTaxName() throws PSMBeanException,
0614: java.net.UnknownHostException {
0615: if (!AdminUtil.isLocal(host)) {
0616: try {
0617: JMXConnector jmxc = AdminServerUtil
0618: .getJMXConnector(host);
0619: MBeanServerConnection msc = jmxc
0620: .getMBeanServerConnection();
0621: Object[] params = {};
0622: String[] signatures = {};
0623: String result = (String) msc.invoke(objectName,
0624: "retrieveTaxName", params, signatures);
0625: jmxc.close();
0626: return result;
0627: } catch (Exception e) {
0628: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
0629: throw new PSMBeanException("Category:retrieveTaxName",
0630: e.toString(), e);
0631: }
0632: } else {
0633: try {
0634: return getTaxTreeNodeName(RDMTaxonomy.RDM_TAXONOMY_ROOT);
0635: } catch (Exception e) {
0636: //logger.logp(Level.SEVERE, "Category", "retrieveTaxName()", "Exception- " + e.getMessage());
0637: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
0638: throw new PSMBeanException(
0639: "errorcode.search.category.tax.name");
0640: }
0641: }
0642: }
0643:
0644: public String retrieveTaxDesc() throws PSMBeanException,
0645: java.net.UnknownHostException {
0646: if (!AdminUtil.isLocal(host)) {
0647: try {
0648: JMXConnector jmxc = AdminServerUtil
0649: .getJMXConnector(host);
0650: MBeanServerConnection msc = jmxc
0651: .getMBeanServerConnection();
0652: Object[] params = {};
0653: String[] signatures = {};
0654: String result = (String) msc.invoke(objectName,
0655: "retrieveTaxDesc", params, signatures);
0656: jmxc.close();
0657: return result;
0658: } catch (Exception e) {
0659: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
0660: throw new PSMBeanException("Category:retrieveTaxDesc",
0661: e.toString(), e);
0662: }
0663: } else {
0664: if (tax != null)
0665: return tax.getDescription();
0666: else
0667: return null;
0668: }
0669: }
0670:
0671: public String retrieveTaxTreeRootName() throws PSMBeanException,
0672: java.net.UnknownHostException {
0673: if (!AdminUtil.isLocal(host)) {
0674: try {
0675: JMXConnector jmxc = AdminServerUtil
0676: .getJMXConnector(host);
0677: MBeanServerConnection msc = jmxc
0678: .getMBeanServerConnection();
0679: Object[] params = {};
0680: String[] signatures = {};
0681: String result = (String) msc.invoke(objectName,
0682: "retrieveTaxTreeRootName", params, signatures);
0683: jmxc.close();
0684: return result;
0685: } catch (Exception e) {
0686: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
0687: throw new PSMBeanException(
0688: "Category:retrieveTaxTreeRootName", e
0689: .toString(), e);
0690: }
0691: } else {
0692: if (root != null)
0693: return root.getId();
0694: else
0695: return null;
0696: }
0697: }
0698:
0699: public String getTaxTreeNodeName(String nodeId)
0700: throws PSMBeanException, java.net.UnknownHostException {
0701: if (!AdminUtil.isLocal(host)) {
0702: try {
0703: JMXConnector jmxc = AdminServerUtil
0704: .getJMXConnector(host);
0705: MBeanServerConnection msc = jmxc
0706: .getMBeanServerConnection();
0707: Object[] params = { nodeId };
0708: String[] signatures = { "java.lang.String" };
0709: String result = (String) msc.invoke(objectName,
0710: "getTaxTreeNodeName", params, signatures);
0711: jmxc.close();
0712: return result;
0713: } catch (Exception e) {
0714: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
0715: throw new PSMBeanException(
0716: "Category:getTaxTreeNodeName", e.toString(), e);
0717: }
0718: } else {
0719:
0720: RDMClassification node = (RDMClassification) tax
0721: .find(nodeId);
0722: try {
0723: if (node != null) {
0724: // The root node correspond actually to the Taxonomy
0725: if (node.getParent() == null) {
0726: // The node is the root node.
0727: // the name shown should be the one of the Taxonomy not the ROOT
0728: return tax.getId();
0729: } else {
0730: // this is a classification node
0731: return node.getId();
0732: }
0733: } else {
0734: //logger.logp(Level.SEVERE, "Category", "getTaxTreeNodeName()", "didn't find the node " + nodeId + "in the taxonomy tree");
0735: Object tokens[] = { "Category.getTaxTreeNodeName(): can't find the node in the taxonomy tree" };
0736: logger
0737: .log(Level.SEVERE, "PSSH_CSPSAMB0002",
0738: tokens);
0739: return null;
0740: }
0741: } catch (Exception e) {
0742: //logger.logp(Level.SEVERE, "Category", "getTaxTreeNodeName()", "Exception- " + e.getMessage());
0743: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
0744: throw new PSMBeanException(
0745: "errorcode.search.category.taxtree.node",
0746: "Category.getTaxTreeNodeName()", e);
0747: }
0748:
0749: }
0750: }
0751:
0752: public String getTaxTreeNodeDesc(String nodeId)
0753: throws PSMBeanException, java.net.UnknownHostException {
0754: if (!AdminUtil.isLocal(host)) {
0755: try {
0756: JMXConnector jmxc = AdminServerUtil
0757: .getJMXConnector(host);
0758: MBeanServerConnection msc = jmxc
0759: .getMBeanServerConnection();
0760: Object[] params = { nodeId };
0761: String[] signatures = { "java.lang.String" };
0762: String result = (String) msc.invoke(objectName,
0763: "getTaxTreeNodeDesc", params, signatures);
0764: jmxc.close();
0765: return result;
0766: } catch (Exception e) {
0767: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
0768: throw new PSMBeanException(
0769: "Category:getTaxTreeNodeDesc", e.toString(), e);
0770: }
0771: } else {
0772:
0773: RDMClassification node = (RDMClassification) tax
0774: .find(nodeId);
0775: try {
0776: if (node != null) {
0777: if (node == root) {
0778: return tax.getDescription();
0779: } else {
0780: return node.getDescription();
0781: }
0782: } else {
0783: //logger.logp(Level.SEVERE, "Category", "getTaxTreeNodeDesc()", "didn't find the node " + nodeId + "in the taxonomy tree");
0784: Object tokens[] = { "Category.getTaxTreeNodeDesc(): can't find the node in the taxonomy tree" };
0785: logger
0786: .log(Level.SEVERE, "PSSH_CSPSAMB0002",
0787: tokens);
0788: return null;
0789: }
0790: } catch (Exception e) {
0791: //logger.logp(Level.SEVERE, "Category", "getTaxTreeNodeDesc()", "Exception- " + e.getMessage());
0792: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
0793: throw new PSMBeanException(
0794: "errorcode.search.category.taxtree.node",
0795: "Category.getTaxTreeNodeDesc()", e);
0796: }
0797:
0798: }
0799: }
0800:
0801: public String getTaxTreeNodeRule(String nodeId)
0802: throws PSMBeanException, java.net.UnknownHostException {
0803: if (!AdminUtil.isLocal(host)) {
0804: try {
0805: JMXConnector jmxc = AdminServerUtil
0806: .getJMXConnector(host);
0807: MBeanServerConnection msc = jmxc
0808: .getMBeanServerConnection();
0809: Object[] params = { nodeId };
0810: String[] signatures = { "java.lang.String" };
0811: String result = (String) msc.invoke(objectName,
0812: "getTaxTreeNodeRule", params, signatures);
0813: jmxc.close();
0814: return result;
0815: } catch (Exception e) {
0816: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
0817: throw new PSMBeanException(
0818: "Category:getTaxTreeNodeRule", e.toString(), e);
0819: }
0820: } else {
0821:
0822: RDMClassification node = (RDMClassification) tax
0823: .find(nodeId);
0824: try {
0825: if (node != null) {
0826: if (node == root) {
0827: return null;
0828: } else {
0829: return node.getMatchingRule();
0830: }
0831: } else {
0832: //logger.logp(Level.SEVERE, "Category", "getTaxTreeNodeRule()", "didn't find the node " + nodeId + "in the taxonomy tree");
0833: Object tokens[] = { "Category.getTaxTreeNodeRule(): can't find the node in the taxonomy tree" };
0834: logger
0835: .log(Level.SEVERE, "PSSH_CSPSAMB0002",
0836: tokens);
0837: return null;
0838: }
0839: } catch (Exception e) {
0840: //logger.logp(Level.SEVERE, "Category", "getTaxTreeNodeRule()", "Exception- " + e.getMessage());
0841: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
0842: throw new PSMBeanException(
0843: "errorcode.search.category.taxtree.node",
0844: "Category.getTaxTreeNodeRule()", e);
0845: }
0846:
0847: }
0848: }
0849:
0850: public ArrayList getTaxTreeDescendance(String parentID)
0851: throws PSMBeanException, java.net.UnknownHostException {
0852: if (!AdminUtil.isLocal(host)) {
0853: try {
0854: JMXConnector jmxc = AdminServerUtil
0855: .getJMXConnector(host);
0856: MBeanServerConnection msc = jmxc
0857: .getMBeanServerConnection();
0858: Object[] params = { parentID };
0859: String[] signatures = { "java.lang.String" };
0860: ArrayList result = (ArrayList) msc.invoke(objectName,
0861: "getTaxTreeDescendance", params, signatures);
0862: jmxc.close();
0863: return result;
0864: } catch (Exception e) {
0865: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
0866: throw new PSMBeanException(
0867: "Category:getTaxTreeDescendance", e.toString(),
0868: e);
0869: }
0870: } else {
0871: if (parentID == null) {
0872: Object tokens[] = { "Category.getTaxTreeDescendance(): can't get the descendance because the node is null" };
0873: logger.log(Level.SEVERE, "PSSH_CSPSAMB0002", tokens);
0874: return null;
0875: }
0876:
0877: try {
0878: // search the parent ID in the tree
0879: RDMClassification node;
0880: if (parentID.equalsIgnoreCase("root")) {
0881: node = root;
0882: } else {
0883: node = this .tax.find(parentID);
0884: }
0885: // build the array
0886: ArrayList descendance = new ArrayList();
0887: getDescendance(node, descendance);
0888:
0889: // return result
0890: return descendance;
0891:
0892: } catch (Exception e) {
0893: //logger.logp(Level.SEVERE, "Category", "getTaxTreeDescendance()", "Cannot get the descendance of node " + parentID + "\n" + e.getMessage());
0894: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
0895: throw new PSMBeanException(
0896: "errorcode.search.category.taxtree.descendance",
0897: "Category.getTaxTreeDescendance()", e);
0898: }
0899:
0900: }
0901: }
0902:
0903: public ArrayList getTaxTreeChildren(String nodeID)
0904: throws PSMBeanException, java.net.UnknownHostException {
0905: if (!AdminUtil.isLocal(host)) {
0906: try {
0907: JMXConnector jmxc = AdminServerUtil
0908: .getJMXConnector(host);
0909: MBeanServerConnection msc = jmxc
0910: .getMBeanServerConnection();
0911: Object[] params = { nodeID };
0912: String[] signatures = { "java.lang.String" };
0913: ArrayList result = (ArrayList) msc.invoke(objectName,
0914: "getTaxTreeChildren", params, signatures);
0915: jmxc.close();
0916: return result;
0917: } catch (Exception e) {
0918: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
0919: throw new PSMBeanException(
0920: "Category:getTaxTreeChildren", e.toString(), e);
0921: }
0922: } else {
0923:
0924: if (nodeID == null) {
0925: Object tokens[] = { "Category.getTaxTreeChildren(): can't get the children nodes because the node is null" };
0926: logger.log(Level.SEVERE, "PSSH_CSPSAMB0002", tokens);
0927: return null;
0928: }
0929:
0930: ArrayList children = new ArrayList();
0931: try {
0932: RDMClassification parent = tax.find(nodeID);
0933: List childs = parent.getChildren();
0934:
0935: if (childs == null)
0936: return children;
0937:
0938: // build the array
0939: for (int i = 0; i < childs.size(); i++) {
0940: RDMClassification childRc = (RDMClassification) childs
0941: .get(i);
0942: children.add(childRc.getId());
0943: }
0944:
0945: } catch (Exception e) {
0946: //logger.logp(Level.SEVERE, "Category", "getTaxTreeChildren()", "Cannot get the children of node " + nodeID + "\n" + e.getMessage());
0947: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
0948: throw new PSMBeanException(
0949: "errorcode.search.category.taxtree.children",
0950: "Category.getTaxTreeChildren()", e);
0951: }
0952:
0953: return children;
0954: }
0955: }
0956:
0957: public Boolean deleteTaxTreeNode(String nodeID)
0958: throws PSMBeanException, java.net.UnknownHostException {
0959: if (!AdminUtil.isLocal(host)) {
0960: try {
0961: JMXConnector jmxc = AdminServerUtil
0962: .getJMXConnector(host);
0963: MBeanServerConnection msc = jmxc
0964: .getMBeanServerConnection();
0965: Object[] params = { nodeID };
0966: String[] signatures = { "java.lang.String" };
0967: Boolean result = (Boolean) msc.invoke(objectName,
0968: "deleteTaxTreeNode", params, signatures);
0969: jmxc.close();
0970: return result;
0971: } catch (Exception e) {
0972: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
0973: throw new PSMBeanException(
0974: "Category:deleteTaxTreeNode", e.toString(), e);
0975: }
0976: } else {
0977: try {
0978: RDMClassification node = tax.find(nodeID);
0979: RDMClassification parent = node.getParent();
0980: if (parent != null) {
0981: int nodeNbDescendant = node.getNumDescendant();
0982: int parentNbChildren = parent.nChildren();
0983: int childIndex = parent.getChildren().indexOf(node);
0984: parent.getChildren().remove(childIndex);
0985: Collections.sort(parent.getChildren());
0986:
0987: // updating ascendants' num of descendants
0988: int i = 0;
0989: for (RDMClassification asc = parent; asc != null;) {
0990: int cur = asc.getNumDescendant();
0991: asc.setNumDescendant(cur
0992: - (nodeNbDescendant + 1));
0993: asc = asc.getParent();
0994: }
0995: } else {
0996: // this is the ROOT selected
0997: // create an empty Taxonomy named Search out of the i18n property file
0998: // this is the root => no parent
0999: try {
1000: //tax = new RDMTaxonomy(getLocalizedString("category.edit.default_taxonomy_name"));
1001: tax = new RDMTaxonomy("Search"); //XXX ask ken
1002: root = tax.find(RDMTaxonomy.RDM_TAXONOMY_ROOT);
1003: } catch (Exception e) {
1004: //logger.logp(Level.SEVERE, "Category", "deleteTaxTreeNode()", "failed to delete the category " + nodeID + ". Didn't find it in taxonomy\n" + e.getMessage());
1005: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
1006: throw new PSMBeanException(
1007: "errorcode.search.category.taxtree.delete",
1008: "Category.deleteTaxTreeNode()", e);
1009: }
1010: }
1011: save();
1012: } catch (NullPointerException e) {
1013: //logger.logp(Level.SEVERE, "Category", "deleteTaxTreeNode()", "failed to delete the category " + nodeID + "\n" + e.getMessage());
1014: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
1015: throw new PSMBeanException(
1016: "errorcode.search.category.taxtree.delete.default",
1017: "Category.deleteTaxTreeNode()", e);
1018: } catch (Exception e) {
1019: //logger.logp(Level.SEVERE, "Category", "deleteTaxTreeNode()", "failed to delete the category " + nodeID + ". Didn't find it in taxonomy\n" + e.getMessage());
1020: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
1021: throw new PSMBeanException(
1022: "errorcode.search.category.taxtree.delete",
1023: "Category.deleteTaxTreeNode()", e);
1024: }
1025:
1026: modified = true;
1027: return Boolean.TRUE;
1028: }
1029: }
1030:
1031: public Boolean insertTaxTreeChildNode(String parentId,
1032: String childId, String childDesc, String childRule)
1033: throws PSMBeanException, java.net.UnknownHostException {
1034: if (!AdminUtil.isLocal(host)) {
1035: try {
1036: JMXConnector jmxc = AdminServerUtil
1037: .getJMXConnector(host);
1038: MBeanServerConnection msc = jmxc
1039: .getMBeanServerConnection();
1040: Object[] params = { parentId, childId, childDesc,
1041: childRule };
1042: String[] signatures = { "java.lang.String",
1043: "java.lang.String", "java.lang.String",
1044: "java.lang.String" };
1045: Boolean result = (Boolean) msc.invoke(objectName,
1046: "insertTaxTreeChildNode", params, signatures);
1047: jmxc.close();
1048: return result;
1049: } catch (Exception e) {
1050: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
1051: throw new PSMBeanException(
1052: "Category:insertTaxTreeChildNode",
1053: e.toString(), e);
1054: }
1055: } else {
1056:
1057: if (childDesc == null)
1058: childDesc = "";
1059:
1060: if (childRule == null)
1061: childRule = "";
1062:
1063: try {
1064: if (this .tax == null) {
1065: //logger.logp(Level.SEVERE, "Category", "insertTaxTreeChildNode()", "failed to insert the category " + childId);
1066: throw new PSMBeanException(
1067: "errorcode.search.category.taxtree.insert");
1068: }
1069: RDMClassification nodeTax = this .tax.find(parentId);
1070: insertChildNode(nodeTax, childId, childDesc, childRule);
1071:
1072: } catch (NullPointerException e) {
1073: //logger.logp(Level.SEVERE, "Category", "insertTaxTreeChildNode()", "failed to insert the category " + childId + "\n" + e.getMessage());
1074: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
1075: throw new PSMBeanException(
1076: "errorcode.search.category.taxtree.insert.default",
1077: "Category.insertTaxTreeChildNode()", e);
1078: } catch (Exception e) {
1079: //logger.logp(Level.SEVERE, "Category", "insertTaxTreeChildNode()", "failed to insert the category " + childId + "\n" + e.getMessage());
1080: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
1081: throw new PSMBeanException(
1082: "errorcode.search.category.taxtree.insert",
1083: "Category.insertTaxTreeChildNode()", e);
1084: }
1085:
1086: modified = true;
1087: return Boolean.TRUE;
1088: }
1089: }
1090:
1091: public Boolean insertTaxTreeSiblingNode(String nodeId,
1092: String siblingId, String siblingDesc, String siblingRule)
1093: throws PSMBeanException, java.net.UnknownHostException {
1094: if (!AdminUtil.isLocal(host)) {
1095: try {
1096: JMXConnector jmxc = AdminServerUtil
1097: .getJMXConnector(host);
1098: MBeanServerConnection msc = jmxc
1099: .getMBeanServerConnection();
1100: Object[] params = { nodeId, siblingId, siblingDesc,
1101: siblingRule };
1102: String[] signatures = { "java.lang.String",
1103: "java.lang.String", "java.lang.String",
1104: "java.lang.String" };
1105: Boolean result = (Boolean) msc.invoke(objectName,
1106: "insertTaxTreeSiblingNode", params, signatures);
1107: jmxc.close();
1108: return result;
1109: } catch (Exception e) {
1110: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
1111: throw new PSMBeanException(
1112: "Category:insertTaxTreeSiblingNode", e
1113: .toString(), e);
1114: }
1115: } else {
1116: try {
1117: if (this .tax == null) {
1118: //logger.logp(Level.SEVERE, "Category", "insertTaxTreeSilbingNode()", "failed to insert the category " + siblingId);
1119: throw new PSMBeanException(
1120: "errorcode.search.category.taxtree.insert");
1121: }
1122: RDMClassification nodeTax = this .tax.find(nodeId)
1123: .getParent();
1124: insertChildNode(nodeTax, siblingId, siblingDesc,
1125: siblingRule);
1126:
1127: } catch (NullPointerException e) {
1128: //logger.logp(Level.SEVERE, "Category", "insertTaxTreeSiblingNode()", "failed to insert the category " + siblingId + " as a sibling to " + nodeId + "\n" + e.getMessage());
1129: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
1130: throw new PSMBeanException(
1131: "errorcode.search.category.taxtree.insert.default",
1132: "Category.insertTaxTreeSilbingNode()", e);
1133: } catch (Exception e) {
1134: //logger.logp(Level.SEVERE, "Category", "insertTaxTreeSiblingNode()", "failed to insert the category " + siblingId + " as a sibling to " + nodeId + "\n" + e.getMessage());
1135: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
1136: throw new PSMBeanException(
1137: "errorcode.search.category.taxtree.insert",
1138: "Category.insertTaxTreeSilbingNode()", e);
1139: }
1140:
1141: modified = true;
1142: return Boolean.TRUE;
1143: }
1144: }
1145:
1146: public Boolean updateTaxTreeNode(String currentId, String newId,
1147: String newDesc, String newRule) throws PSMBeanException,
1148: java.net.UnknownHostException {
1149: if (!AdminUtil.isLocal(host)) {
1150: try {
1151: JMXConnector jmxc = AdminServerUtil
1152: .getJMXConnector(host);
1153: MBeanServerConnection msc = jmxc
1154: .getMBeanServerConnection();
1155: Object[] params = { currentId, newId, newDesc, newRule };
1156: String[] signatures = { "java.lang.String",
1157: "java.lang.String", "java.lang.String",
1158: "java.lang.String" };
1159: Boolean result = (Boolean) msc.invoke(objectName,
1160: "updateTaxTreeNode", params, signatures);
1161: jmxc.close();
1162: return result;
1163: } catch (Exception e) {
1164: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
1165: throw new PSMBeanException(
1166: "Category:updateTaxTreeNode", e.toString(), e);
1167: }
1168: } else {
1169: try {
1170: if (newId.trim() != "") {
1171: // modify the current selected node
1172: RDMClassification node = this .tax.find(currentId);
1173: StringBuffer sb = new StringBuffer();
1174: if (node.getParentId() == null) {
1175: // if the selected node is the Root the newId becomes also the
1176: // name of the Taxonomy
1177: updateTaxonomy(newId, newDesc);
1178: } else {
1179: // if parent is Root reject rename child same as ROOT or taxId
1180: if (node.getParent() == root) {
1181: if ((newId.equals(tax.getId()))
1182: || (newId
1183: .equals(RDMTaxonomy.RDM_TAXONOMY_ROOT))) {
1184: if (newId
1185: .equals(RDMTaxonomy.RDM_TAXONOMY_ROOT)) {
1186: //logger.logp(Level.SEVERE, "Category", "updateTaxTreeNode()", "ROOT is invalid classification name under the root");
1187: throw new PSMBeanException(
1188: "errorcode.search.category.taxtree.rootchild");
1189: } else {
1190: //logger.logp(Level.SEVERE, "Category", "updateTaxTreeNode()", "The top most Categories name must differ from the Taxonomy name");
1191: throw new PSMBeanException(
1192: "errorcode.search.category.taxtree.differfromtax");
1193: }
1194: }
1195: }
1196: if (currentId.indexOf(':') != -1) {
1197: // build the new id with the prefix of current id
1198: sb.append(currentId.substring(0, currentId
1199: .lastIndexOf(":")));
1200: sb.append(":" + newId);
1201: } else {
1202: sb.append(newId);
1203: }
1204: // if we are renaming the node, reject if same as sibling
1205: boolean reject = false;
1206: if (!newId.equals(lastNode(currentId))) {
1207: // verify that the new name differs from existing siblings
1208: RDMClassification parentRc = node
1209: .getParent();
1210: for (int i = 0; i < parentRc.nChildren(); i++) {
1211: if (parentRc.nthChild(i).getId()
1212: .equals(sb.toString())) {
1213: reject = true;
1214: break;
1215: }
1216: }
1217: }
1218: if (reject) {
1219: //logger.logp(Level.SEVERE, "Category", "updateTaxTreeNode()", "Failed to update the category because the new name already exists in the taxonomy");
1220: throw new PSMBeanException(
1221: "errorcode.search.category.taxtree.update.newexist");
1222: }
1223: node.setSubcategory(sb.toString());
1224: recurseUpdateNode(node, currentId, sb
1225: .toString());
1226: node.setDescription(newDesc);
1227: node.setMatchingRule(newRule);
1228: save();
1229: }
1230: } else {
1231: //logger.logp(Level.SEVERE, "Category", "updateTaxTreeNode()", "Failed to update the category " + currentId);
1232: throw new PSMBeanException(
1233: "errorcode.search.category.taxtree.update");
1234: }
1235: } catch (NullPointerException npe) {
1236: //logger.logp(Level.SEVERE, "Category", "updateTaxTreeNode()", "Failed to update the category for null pointer exception\n" + npe.getMessage());
1237: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", npe);
1238: throw new PSMBeanException(
1239: "errorcode.search.category.taxtree.update.default",
1240: "Category.updateTaxTreeNode()", npe);
1241: } catch (Exception e) {
1242: //logger.logp(Level.SEVERE, "Category", "updateTaxTreeNode()", "failed to update the category " + currentId + "with Exception: " + e.getMessage());
1243: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
1244: throw new PSMBeanException(
1245: "errorcode.search.category.taxtree.update",
1246: "Category.updateTaxTreeNode()", e);
1247: }
1248:
1249: modified = true;
1250: return Boolean.TRUE;
1251: }
1252: }
1253:
1254: public ArrayList searchTaxTree(String searchserver, String query,
1255: String numOfHits, String scope) throws PSMBeanException,
1256: java.net.UnknownHostException {
1257: if (!AdminUtil.isLocal(host)) {
1258: try {
1259: JMXConnector jmxc = AdminServerUtil
1260: .getJMXConnector(host);
1261: MBeanServerConnection msc = jmxc
1262: .getMBeanServerConnection();
1263: Object[] params = { searchserver, query, numOfHits,
1264: scope };
1265: String[] signatures = { "java.lang.String",
1266: "java.lang.String", "java.lang.String",
1267: "java.lang.String" };
1268: ArrayList result = (ArrayList) msc.invoke(objectName,
1269: "searchTaxTree", params, signatures);
1270: jmxc.close();
1271: return result;
1272: } catch (Exception e) {
1273: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
1274: throw new PSMBeanException("Category:searchTaxTree", e
1275: .toString(), e);
1276: }
1277: } else {
1278: ArrayList results = new ArrayList();
1279: int count = 0;
1280: int hits = Integer.parseInt(numOfHits);
1281: try {
1282: search.setRDMServer(searchserver);
1283: search.setQueryLanguage("search");
1284: search.setRDMType("taxonomy-request");
1285: search.setViewAttributes("id"); //fine tune later
1286: search.setViewHits(hits);
1287: if (scope == null || scope.equals("")
1288: || scope.equalsIgnoreCase("all")) {
1289: search.setScope("category <contains> (<or> "
1290: + query + ") <and> (<or> " + query + ")"); //search the entire taxonomy tree
1291: } else {
1292: search.setScope("category <contains> (<or> "
1293: + query + ") <and> (Id <starts> " + scope
1294: + ":)"); //search the current node down
1295: }
1296: search.doQuery();
1297: SOIFInputStream sr = search.getResultStream();
1298: if (sr != null) {
1299: while (!sr.isEOS()) {
1300: SOIF se = sr.readSOIF();
1301: if (se != null) {
1302: String catId = se.getValue("Id");
1303: results.add(catId);
1304: count++;
1305: if (count == hits)
1306: break;
1307: } else {
1308: continue;
1309: }
1310: }
1311: }
1312: } catch (IOException ioe) {
1313: Object tokens[] = { "Category.searchTaxTree(): failed to read from SOIFInputStream" };
1314: logger.log(Level.SEVERE, "PSSH_CSPSAMB0002", tokens);
1315: } catch (NullPointerException npe) {
1316: Object tokens[] = { "Category.searchTaxTree(): null pointer" };
1317: logger.log(Level.SEVERE, "PSSH_CSPSAMB0002", tokens);
1318: } catch (Exception e) {
1319: Object tokens[] = { "Category.searchTaxTree(): failed to search the taxonomy for server "
1320: + searchserver };
1321: logger.log(Level.SEVERE, "PSSH_CSPSAMB0002", tokens);
1322: }
1323:
1324: return results;
1325: }
1326: }
1327:
1328: public String reindexTaxTree() throws PSMBeanException,
1329: java.net.UnknownHostException {
1330: if (!AdminUtil.isLocal(host)) {
1331: try {
1332: JMXConnector jmxc = AdminServerUtil
1333: .getJMXConnector(host);
1334: MBeanServerConnection msc = jmxc
1335: .getMBeanServerConnection();
1336: Object[] params = {};
1337: String[] signatures = {};
1338: String result = (String) msc.invoke(objectName,
1339: "reindexTaxTree", params, signatures);
1340: jmxc.close();
1341: return result;
1342: } catch (Exception e) {
1343: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
1344: throw new PSMBeanException("Category:reindexTaxTree", e
1345: .toString(), e);
1346: }
1347: } else {
1348: String cmd = serverRoot + File.separator
1349: + Platform.getCommand("run-cs-cli")
1350: + " rdmgr -I -T -p stdout";
1351: String output = "";
1352: Runtime rt = Runtime.getRuntime();
1353: try {
1354: Process process = rt.exec(cmd);
1355: BufferedReader buf = new BufferedReader(
1356: new InputStreamReader(process.getInputStream()));
1357: String outLine = null;
1358: while ((outLine = buf.readLine()) != null) {
1359: output = output + " <BR> " + outLine;
1360: }
1361: process.waitFor();
1362: } catch (Exception e) {
1363: Object tokens[] = { "Category.reindexTaxTree(): failed to reindex the taxonomy" };
1364: logger.log(Level.SEVERE, "PSSH_CSPSAMB0002", tokens);
1365: }
1366: modified = false;
1367: return output;
1368: }
1369: }
1370:
1371: public Boolean needReindex() throws PSMBeanException,
1372: java.net.UnknownHostException {
1373: if (!AdminUtil.isLocal(host)) {
1374: try {
1375: JMXConnector jmxc = AdminServerUtil
1376: .getJMXConnector(host);
1377: MBeanServerConnection msc = jmxc
1378: .getMBeanServerConnection();
1379: Object[] params = {};
1380: String[] signatures = {};
1381: Boolean result = (Boolean) msc.invoke(objectName,
1382: "needReindex", params, signatures);
1383: jmxc.close();
1384: return result;
1385: } catch (Exception e) {
1386: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
1387: throw new PSMBeanException("Category:needReindex", e
1388: .toString(), e);
1389: }
1390: } else {
1391: if (modified) {
1392: return Boolean.TRUE;
1393: } else {
1394: return Boolean.FALSE;
1395: }
1396: }
1397: }
1398:
1399: public Boolean isOutOfSync() throws PSMBeanException,
1400: java.net.UnknownHostException {
1401: if (!AdminUtil.isLocal(host)) {
1402: try {
1403: JMXConnector jmxc = AdminServerUtil
1404: .getJMXConnector(host);
1405: MBeanServerConnection msc = jmxc
1406: .getMBeanServerConnection();
1407: Object[] params = {};
1408: String[] signatures = {};
1409: Boolean result = (Boolean) msc.invoke(objectName,
1410: "isOutOfSync", params, signatures);
1411: jmxc.close();
1412: return result;
1413: } catch (Exception e) {
1414: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
1415: throw new PSMBeanException("Category:isOutOfSync", e
1416: .toString(), e);
1417: }
1418: } else {
1419: try {
1420: if (isConfigNewer()) {
1421: return Boolean.TRUE;
1422: }
1423: } catch (PSMBeanException e) {
1424: throw e;
1425: }
1426: return Boolean.FALSE;
1427: }
1428: }
1429:
1430: public Boolean syncTaxFile() throws PSMBeanException,
1431: java.net.UnknownHostException {
1432: if (!AdminUtil.isLocal(host)) {
1433: try {
1434: JMXConnector jmxc = AdminServerUtil
1435: .getJMXConnector(host);
1436: MBeanServerConnection msc = jmxc
1437: .getMBeanServerConnection();
1438: Object[] params = {};
1439: String[] signatures = {};
1440: Boolean result = (Boolean) msc.invoke(objectName,
1441: "syncTaxFile", params, signatures);
1442: jmxc.close();
1443: return result;
1444: } catch (Exception e) {
1445: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
1446: throw new PSMBeanException("Category:syncTaxFile", e
1447: .toString(), e);
1448: }
1449: } else {
1450: try {
1451: if (isConfigNewer()) { //file copy is newer
1452: load();
1453: modified = true;
1454: return Boolean.TRUE;
1455: }
1456: } catch (PSMBeanException e) {
1457: throw e;
1458: }
1459: return Boolean.FALSE;
1460: }
1461: }
1462:
1463: /*
1464: * Methods for internal use
1465: */
1466:
1467: /*
1468: * returns all descendante children ID given a start parent ID
1469: */
1470: private void getDescendance(RDMClassification rc,
1471: ArrayList descendance) {
1472: //logger.logp(Level.SEVERE, "Category", "getDescendance()", "rc is " + rc);
1473: // add all direct children to the descendante array
1474: // recursively adds grand children
1475: for (int i = 0; i < rc.nChildren(); i++) {
1476: RDMClassification childRc = rc.nthChild(i);
1477: //logger.logp(Level.SEVERE, "Category", "getDescendance()", "childRc id " + childRc.getId());
1478: descendance.add(childRc.getId());
1479: getDescendance(childRc, descendance);
1480: }
1481: }
1482:
1483: public void insertChildNode(RDMClassification rc, String childId,
1484: String childDesc, String childRule) throws Exception {
1485: try {
1486: String childAbsolutID = null;
1487: if (rc == root) {
1488: childAbsolutID = childId;
1489: } else {
1490: childAbsolutID = rc.getId() + ":" + childId;
1491: }
1492: if (rc != null) {
1493: if ((rc == root)
1494: && (childId
1495: .equals(RDMTaxonomy.RDM_TAXONOMY_ROOT) || childId
1496: .equals(tax.getId()))) {
1497: // 1st level child cannot be ROOT or same name as taxonomy
1498: if (childId.equals(RDMTaxonomy.RDM_TAXONOMY_ROOT)) {
1499: //logger.logp(Level.SEVERE, "Category", "insertChildNode()", "ROOT is invalid classification name under the root");
1500: throw new Exception(
1501: "ROOT is invalid classification name under the root of the taxonomy");
1502:
1503: } else {
1504: //logger.logp(Level.SEVERE, "Category", "insertChildNode()", "The taxonomy Name must differ from all top most Categories name");
1505: throw new Exception(
1506: "The taxonomy Name must differ from all top most Categories name");
1507: }
1508: }
1509: // use similar method to the one used in RDMTaxonomy's constructor
1510: // 1. check if the child doesn't already exist
1511: if (tax.find(childAbsolutID) == null) {
1512: // 2. create a new RDMClassification
1513: RDMClassification newRc = newChild(rc, childId,
1514: childDesc, childRule, rc.getTaxonomyId());
1515: if (newRc != null) {
1516: // 3. insert RDMClassification in taxonomy
1517: tax.insert(newRc);
1518: save();
1519: } else {
1520: //logger.logp(Level.SEVERE, "Category", "insertChildNode()", "Failed to add the category " + childAbsolutID + ". Cannot create it.");
1521: throw new Exception(
1522: "Failed to add the category. Cannot create it");
1523: }
1524: } else {
1525: //logger.logp(Level.SEVERE, "Category", "insertChildNode()", "Failed to add the category " + childAbsolutID + " because it already exists in the taxonomy.");
1526: throw new Exception(
1527: "Failed to add the category because it already exists in the taxonomy");
1528: }
1529: } else {
1530: //logger.logp(Level.SEVERE, "Category", "insertChildNode()", "Failed to add the category " + childAbsolutID + " because of no parent category found in the taxonomy.");
1531: throw new Exception(
1532: "Failed to add the category because of no parent category found in the taxonomy");
1533: }
1534: } catch (NullPointerException npe) {
1535: //logger.logp(Level.SEVERE, "Category", "insertChildNode()", "Failed to add the category " + rc + ", " + childId + ", " + childDesc + " to the node " + rc.getId() + " because of Exception: "+ npe.getMessage());
1536: throw new Exception(
1537: "Failed to insert the category due to a system error");
1538: }
1539:
1540: }
1541:
1542: /*
1543: * updates the taxonomy name and recursively update
1544: * all its classification nodes taxonomy-id value
1545: */
1546: public void updateTaxonomy(String newId, String newDesc)
1547: throws Exception {
1548: try {
1549: if (!newId.trim().equals("")) {
1550: // if any root children has the name=newId then reject
1551: boolean reject = false;
1552: for (int i = 0; i < root.nChildren(); i++) {
1553: if (root.nthChild(i).getId().equals(newId)) {
1554: reject = true;
1555: break;
1556: }
1557: }
1558: if (reject) {
1559: //logger.logp(Level.SEVERE, "Category", "updateTaxonomy()", "The top most Categories name must differ from the Taxonomy name");
1560: throw new Exception(
1561: "The top most Categories name must differ from the Taxonomy name");
1562: } else {
1563: // if (!newId.trim().equals(root.getId())) {
1564: // updating all chidren nodes
1565: recurseUpdateNodeTaxonomy(root, newId);
1566:
1567: // change the taxonomyName
1568: tax.setId(newId);
1569: tax.setDescription(newDesc.trim());
1570: save();
1571: }
1572: } else {
1573: //logger.logp(Level.SEVERE, "Category", "updateTaxonomy()", "The taxonomy name is blank");
1574: throw new Exception("The taxonomy name is blank");
1575: }
1576: } catch (NullPointerException e) {
1577: //logger.logp(Level.SEVERE, "Category", "updateTaxonomy()", "Failed to update the category for null pointer exception\n" + e.getMessage());
1578: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
1579: throw new Exception(
1580: "Failed to update the category in the taxonomy due to a system error.");
1581: }
1582: }
1583:
1584: /**
1585: * Updates all classification node's taxonomyID value
1586: */
1587: public void recurseUpdateNodeTaxonomy(RDMClassification rc,
1588: String newId) throws Exception {
1589: try {
1590: // change current node taxonomyId
1591: rc.setTaxonomyId(newId);
1592:
1593: // change all its children one's
1594: for (int i = 0; i < rc.nChildren(); i++) {
1595: recurseUpdateNodeTaxonomy(rc.nthChild(i), newId);
1596: }
1597: } catch (NullPointerException npe) {
1598: String rcStr;
1599: if (rc != null) {
1600: rcStr = rc.getId();
1601: } else {
1602: rcStr = "(rc is NULL)";
1603: }
1604: //logger.logp(Level.SEVERE, "Category", "recurseUpdateNodeTaxonomy()", "Cannot recursivly update taxonomy for children of category " + rcStr);
1605: throw new Exception(
1606: "Cannot recursively update Taxonomy on children of category "
1607: + rcStr);
1608: }
1609: }
1610:
1611: /**
1612: * Update a node's children's 'Id' and 'parentId'
1613: */
1614: public void recurseUpdateNode(RDMClassification node,
1615: String currentId, String newId) throws Exception {
1616:
1617: try {
1618: // if current node's Id is prefixed with currentId rename Id
1619: String nodeId = node.getId();
1620: if (nodeId.startsWith(currentId)) {
1621: StringBuffer newNodeId = new StringBuffer(newId);
1622: String nodeIdSuffix = nodeId.substring(currentId
1623: .length());
1624: if (nodeIdSuffix.length() > 0) {
1625: // past existing suffix portion to newNodeId
1626: newNodeId.append(nodeIdSuffix);
1627: }
1628: node.setId(newNodeId.toString());
1629: }
1630: //if current node's parentId is prefixed with currentId,
1631: //rename parentId
1632: String parentId = node.getParentId();
1633: if (parentId != null) {
1634: if (parentId.startsWith(currentId)) {
1635: StringBuffer newParentNodeId = new StringBuffer(
1636: newId);
1637: String parentNodeIdSuffix = parentId
1638: .substring(currentId.length());
1639: if (parentNodeIdSuffix.length() > 0) {
1640: // past existing suffix portion to newParentNodeId
1641: newParentNodeId.append(parentNodeIdSuffix);
1642: }
1643: node.setParentId(newParentNodeId.toString());
1644: }
1645: }
1646:
1647: // call same method on all direct children of current node
1648: for (int i = 0; i < node.nChildren(); i++) {
1649: recurseUpdateNode(node.nthChild(i), currentId, newId);
1650: }
1651: } catch (NullPointerException npe) {
1652: //logger.logp(Level.SEVERE, "Category", "recurseUpdateNode()", "Cannot recursivly update children of category " + currentId);
1653: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", npe);
1654: throw new Exception(
1655: "Cannot recursivly update children of category "
1656: + currentId);
1657: }
1658: }
1659:
1660: public void save() {
1661: // save the current taxonomy in file
1662: try {
1663: SOIFOutputStream sos = new SOIFOutputStream(tax_conf_file);
1664: // write taxonomy
1665: sos.write(tax.getSOIF());
1666: sos.flush();
1667: // writes the entire classification
1668: write(sos);
1669: sos.flush();
1670: sos.close();
1671: // purge + reindex DB
1672: if (DBUtil.indexCategories(serverRoot) != true) {
1673: //logger.logp(Level.SEVERE, "Category", "save()", "Failed to to reindex categories");
1674: Object tokens[] = { "Category.save(): failed to reindex categories" };
1675: logger.log(Level.SEVERE, "PSSH_CSPSAMB0002", tokens);
1676: }
1677:
1678: setTimeStamp();
1679:
1680: } catch (FileNotFoundException fnf) {
1681: //logger.logp(Level.SEVERE, "Category", "save()", "The taxonomy configuration file " + tax_conf_file + " is missing\n" + fnf.toString(), fnf);
1682: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", fnf);
1683: } catch (UnsupportedEncodingException ue) {
1684: //logger.logp(Level.SEVERE, "Category", "save()", "The taxonomy configuration file " + tax_conf_file + " is invalid\n" + ue.toString(), ue);
1685: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", ue);
1686: } catch (SOIFException se) {
1687: //logger.logp(Level.SEVERE, "Category", "save()", "The taxonomy configuration file " + tax_conf_file + " is invalid\n" + se.toString(), se);
1688: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", se);
1689: } catch (Exception e) {
1690: //logger.logp(Level.SEVERE, "Category", "save()", "Exception: e.getMessage()\n" + e.toString(), e);
1691: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
1692: }
1693:
1694: }
1695:
1696: public void write(SOIFOutputStream ss) {
1697: write(ss, root);
1698: }
1699:
1700: private void write(SOIFOutputStream ss, RDMClassification rc) {
1701: try {
1702: StringBuffer sb = null;
1703:
1704: if (rc != root) {
1705: // dumping current leaving out the ROOT dummy node
1706: ss.write(rc.getSOIF());
1707: }
1708:
1709: // dumping childrens
1710: if (rc.getNumDescendant() != 0) {
1711: // loop on dumping all the classification
1712: for (int j = 0; j < rc.nChildren(); j++) {
1713: write(ss, rc.nthChild(j));
1714: }
1715: }
1716: } catch (IOException ioe) {
1717: //logger.logp(Level.SEVERE, "Category", "write()", "IOException: " + ioe.getMessage() + "\n" + ioe.toString(), ioe);
1718: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", ioe);
1719: }
1720: }
1721:
1722: /*
1723: * utility to return the lastNode from a classification NodeID
1724: */
1725: public String lastNode(String nodeID) {
1726: try {
1727: String value = null;
1728: if (nodeID != null) {
1729: int ndx = nodeID.lastIndexOf(':');
1730: if (ndx > 0) {
1731: value = nodeID.substring(ndx + 1);
1732: } else {
1733: value = nodeID;
1734: }
1735: } else {
1736: value = null;
1737: }
1738: return value;
1739: } catch (Exception e) {
1740: //logger.logp(Level.SEVERE, "Category", "lastNode()", "Exception: " + e.getMessage() + "\n" + e.toString(), e);
1741: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
1742: return null;
1743: }
1744: }
1745:
1746: /*
1747: * new Classification in the current taxonomy
1748: */
1749: public RDMClassification newChild(RDMClassification parent,
1750: String childId, String childDesc, String childRule,
1751: String taxonomyId) {
1752: try {
1753: if (childId.trim() != "") {
1754: String parentId = parent.getId();
1755: String newId;
1756: if (parentId.equals(RDMTaxonomy.RDM_TAXONOMY_ROOT)) {
1757: newId = childId;
1758: } else {
1759: newId = parentId + ":" + childId;
1760: }
1761: RDMClassification rc = new RDMClassification(newId);
1762: rc.setTaxonomyId(taxonomyId);
1763: rc.setParentId(parentId);
1764: rc.setDescription(childDesc);
1765: rc.setMatchingRule(childRule);
1766: return rc;
1767: } else {
1768: return null;
1769: }
1770: } catch (Exception e) {
1771: //logger.logp(Level.SEVERE, "Category", "newChild()", "Exception: " + e.getMessage() + "\n" + e.toString(), e);
1772: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
1773: return null;
1774: }
1775: }
1776:
1777: /*
1778: * returns true if the taxonomy file is newer than the mbean's timestamp
1779: */
1780: public boolean isConfigNewer() throws PSMBeanException,
1781: java.net.UnknownHostException {
1782: try {
1783: File f = new File(tax_conf_file);
1784: if ((getTimeStamp() != 0)
1785: && (getTimeStamp() < f.lastModified())) {
1786: return true;
1787: } else {
1788: return false;
1789: }
1790: } catch (Exception e) {
1791: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
1792: throw new PSMBeanException(
1793: "Failed to verify the current time stamp of the Taxonomy file.",
1794: "Category.isConfigNewer()", e);
1795: }
1796: }
1797:
1798: /*
1799: * returns the last stored mbean modification date
1800: */
1801: private long getTimeStamp() {
1802: return lastModified;
1803: }
1804:
1805: /*
1806: * set the taxonomy file last modified timestamp
1807: */
1808: private void setTimeStamp() throws PSMBeanException,
1809: java.net.UnknownHostException {
1810: try {
1811: File f = new File(tax_conf_file);
1812: lastModified = f.lastModified();
1813: setLastActionDate(lastModified);
1814: } catch (Exception e) {
1815: logger.log(Level.SEVERE, "PSSH_CSPSAMB0003", e);
1816: throw new PSMBeanException(
1817: "Failed to verify the current time stamp of the Taxonomy file.",
1818: "Category.setTimeStamp()", e);
1819: }
1820: }
1821:
1822: /*
1823: * returns the last Date an action (add/del/update/save/load) was taken
1824: */
1825: public Date getLastActionDate() {
1826: return lastActionDate;
1827: }
1828:
1829: /*
1830: * sets the last Date an action (add/del/update/save/load) was taken
1831: */
1832: private void setLastActionDate(long d) {
1833: lastActionDate = new Date(d);
1834: }
1835:
1836: }
|