Ignore:
Timestamp:
2007-07-09T10:05:55+12:00 (17 years ago)
Author:
xiao
Message:

add a method getFirstElementChild(node)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • greenstone3/trunk/src/java/org/greenstone/gsdl3/util/GSXML.java

    r13994 r14222  
    2121/** various functions for extracting info out of GS XML */
    2222public class GSXML {
    23 
    24     static Logger logger = Logger.getLogger(org.greenstone.gsdl3.util.GSXML.class.getName());
    25 
    26     // greenstone xml elements
    27     public static final String MESSAGE_ELEM = "message";
    28     public static final String REQUEST_ELEM = "request";
    29     public static final String RESPONSE_ELEM = "response";
    30     public static final String COLLECTION_ELEM = "collection";
    31     public static final String SERVICE_ELEM = "service";
    32     public static final String CLUSTER_ELEM = "serviceCluster";
    33     public static final String SITE_ELEM = "site";
    34     public static final String PARAM_ELEM = "param";
    35     public static final String PARAM_OPTION_ELEM = "option";
    36     public static final String CONTENT_ELEM = "content";
    37     public static final String RESOURCE_ELEM = "resource";
    38     public static final String DOCUMENT_ELEM = "document";
    39     public static final String METADATA_ELEM = "metadata";
    40     public static final String SERVICE_CLASS_ELEM = "serviceRack";
    41     public static final String CLASSIFIER_ELEM = "classifier";
    42     public static final String APPLET_ELEM = "applet";
    43     public static final String APPLET_DATA_ELEM = "appletData";
    44     public static final String CONFIGURE_ELEM = "configure";
    45     public static final String STATUS_ELEM = "status";
    46     public static final String ERROR_ELEM = "error";
    47     public static final String DEFAULT_ELEM = "default";
    48     public static final String STYLESHEET_ELEM = "format";//"stylesheet"; // any additional stylesheet stuff is carried in the message inside this elem
    49     public static final String FORMAT_ELEM = "format"; // config files use format - should we use this instead of stylesheet??
    50     public static final String TERM_ELEM = "term";
    51     public static final String SYSTEM_ELEM = "system";
    52 
    53     //config file elems
    54     public static final String COLLECTION_CONFIG_ELEM = "collectionConfig";
    55     public static final String COLLECTION_BUILD_ELEM = "buildConfig";
    56     public static final String COLLECTION_INIT_ELEM = "collectionInit";
    57     public static final String RECOGNISE_ELEM = "recognise";
    58     public static final String DOC_TYPE_ELEM = "docType";
    59     public static final String SEARCH_ELEM = "search";
    60     public static final String INDEX_ELEM = "index";
    61     public static final String INDEX_STEM_ELEM = "indexStem";
    62     public static final String INDEX_OPTION_ELEM = "indexOption";
    63     public static final String BROWSE_ELEM = "browse";
    64     public static final String DISPLAY_ELEM = "display";
    65     public static final String LEVEL_ELEM = "level";
    66     public static final String SHORTNAME_ATT = "shortname";
    67     public static final String NOTIFY_ELEM = "notify";
    68     public static final String NOTIFY_HOST_ATT = "host";
    69 
    70     // elems for the pages to be processed by xslt
    71     public final static String PAGE_ELEM = "page";
    72     public final static String CONFIGURATION_ELEM = "config";
    73     public final static String PAGE_REQUEST_ELEM = "pageRequest";
    74     public final static String PAGE_RESPONSE_ELEM = "pageResponse";
    75     public final static String PAGE_EXTRA_ELEM = "pageExtra";
    76 
    77     //public final static String DESCRIPTION_ELEM = "description";
    78 
    79     public static final String  ACTION_ELEM = "action";
    80     public static final String  SUBACTION_ELEM = "subaction";
    81    
    82     // add on to another elem type to get a list of that type
    83     public static final String LIST_MODIFIER = "List";
    84 
    85     // greenstone xml attributes
    86     public static final String NAME_ATT = "name";
    87     public static final String TO_ATT = "to";
    88     public static final String USER_ID_ATT = "uid";
    89     public static final String FROM_ATT = "from";
    90     public static final String LANG_ATT = "lang";
    91     public static final String TYPE_ATT = "type";
    92     public static final String VALUE_ATT = "value";
    93     public static final String DEFAULT_ATT = "default";
    94     public static final String INFO_ATT = "info";
    95     public static final String ACTION_ATT = "action";
    96     public static final String SUBACTION_ATT = "subaction";
    97     public static final String OUTPUT_ATT = "output";
    98     public static final String ADDRESS_ATT = "address";
    99     public static final String LOCAL_SITE_ATT = "localSite";
    100     public static final String LOCAL_SITE_NAME_ATT = "localSiteName";
    101     public static final String STATUS_ERROR_CODE_ATT = "code";
    102     public static final String STATUS_PROCESS_ID_ATT = "pid";
    103     public static final String PARAM_SHORTNAME_ATT = "shortname";
    104     public static final String PARAM_IGNORE_POS_ATT = "ignore";
    105     public static final String CLASSIFIER_CONTENT_ATT = "content";
    106     public static final String ERROR_TYPE_ATT = "type";
    107 
    108     // document stuff
    109     public static final String DOC_TYPE_ATT = "docType";
    110     public static final String DOC_NODE_ELEM = "documentNode";
    111     public static final String NODE_CONTENT_ELEM = "nodeContent";
    112     public static final String NODE_STRUCTURE_ELEM = "nodeStructure";
    113     public static final String NODE_ID_ATT = "nodeID";
    114     public static final String NODE_NAME_ATT = "nodeName";
    115     public static final String NODE_TYPE_ATT = "nodeType";
    116     public static final String NODE_RANK_ATT = "rank";
    117     public static final String NODE_TYPE_ROOT = "root";
    118     public static final String NODE_TYPE_INTERNAL = "internal";
    119     public static final String NODE_TYPE_LEAF = "leaf";
    120 
    121     public static final String DOC_TYPE_SIMPLE = "simple";
    122     public static final String DOC_TYPE_PAGED = "paged";
    123     public static final String DOC_TYPE_HIERARCHY = "hierarchy";
    124 
    125     // classifier stuff
    126     public static final String CLASS_NODE_ELEM = "classifierNode";
    127     public static final String CLASS_NODE_ORIENTATION_ATT = "orientation";
    128    
    129     // parameter types
    130     public static final String PARAM_TYPE_INTEGER = "integer";
    131     public static final String PARAM_TYPE_BOOLEAN = "boolean";
    132     public static final String PARAM_TYPE_ENUM_START = "enum";
    133     public static final String PARAM_TYPE_ENUM_SINGLE = "enum_single";
    134     public static final String PARAM_TYPE_ENUM_MULTI = "enum_multi";
    135     public static final String PARAM_TYPE_STRING = "string";
    136     public static final String PARAM_TYPE_TEXT = "text";
    137     public static final String PARAM_TYPE_MULTI = "multi";
    138     public static final String PARAM_TYPE_FILE = "file";
    139     public static final String PARAM_TYPE_INVISIBLE = "invisible";
    140     // stuff for text strings
    141     public static final String DISPLAY_TEXT_ELEM = "displayItem";
    142     // the following are used for the name attributes
    143     public static final String DISPLAY_TEXT_NAME = "name";
    144     public static final String DISPLAY_TEXT_SUBMIT = "submit";
    145     public static final String DISPLAY_TEXT_DESCRIPTION = "description";
    146 
    147     // request types
    148     // get the module description
    149     public static final String REQUEST_TYPE_DESCRIBE = "describe";
    150     // startup a process
    151     public static final String REQUEST_TYPE_PROCESS = "process";
    152     // get the status of an ongoing process
    153     public static final String REQUEST_TYPE_STATUS = "status";
    154     // system type request - eg reload a collection
    155     public static final String REQUEST_TYPE_SYSTEM = "system";
    156     // page requests to the Receptionist/Actions
    157     public static final String REQUEST_TYPE_PAGE = "page"; // used to be cgi
    158     // get any format info for a service
    159     public static final String REQUEST_TYPE_FORMAT = "format";
    160     // modify the requests
    161     public static final String REQUEST_TYPE_MESSAGING = "messaging";
    162 
    163     // service types
    164     public static final String SERVICE_TYPE_QUERY = "query";
    165     public static final String SERVICE_TYPE_RETRIEVE = "retrieve";
    166     public static final String SERVICE_TYPE_BROWSE = "browse";
    167     public static final String SERVICE_TYPE_APPLET = "applet";
    168     public static final String SERVICE_TYPE_PROCESS = "process";
    169     public static final String SERVICE_TYPE_ENRICH = "enrich";
    170 
    171     // system command types and attributes
    172     public static final String SYSTEM_TYPE_CONFIGURE = "configure";
    173     public static final String SYSTEM_TYPE_ACTIVATE = "activate";
    174     public static final String SYSTEM_TYPE_DEACTIVATE = "deactivate";
    175 
    176     public static final String SYSTEM_SUBSET_ATT = "subset";
    177     public static final String SYSTEM_MODULE_TYPE_ATT = "moduleType";
    178     public static final String SYSTEM_MODULE_NAME_ATT = "moduleName";
    179    
    180     // communicator types
    181     public static final String COMM_TYPE_SOAP_JAVA = "soap";
    182    
    183     // error types
    184     public static final String ERROR_TYPE_SYNTAX = "syntax";
    185     public static final String ERROR_TYPE_SYSTEM = "system";
    186     public static final String ERROR_TYPE_INVALID_ID = "invalid_id";
    187     public static final String ERROR_TYPE_OTHER = "other";
    188 
    189     // some system wide param names
    190     public static final String SUBSET_PARAM = "subset";
    191    
    192     //for plugin
    193     public static final String PLUGIN_ELEM = "plugin";
    194     public static final String IMPORT_ELEM = "import";
    195    
    196    
    197     /** takes a list of elements, and returns an array of strings
    198      * of the values of attribute att_name */
    199     public static String [] getAttributeValuesFromList(Element list,
    200                                String att_name) {
    201    
    202     NodeList children = list.getChildNodes();
    203    
    204     int num_nodes = children.getLength();
    205     String []ids = new String[num_nodes];
    206     for (int i=0; i<num_nodes; i++) {
    207         Element e = (Element)children.item(i);
    208         String id = e.getAttribute(att_name);       
    209         ids[i] = id;       
    210     }
    211    
    212     return ids;
    213     }
    214 
    215     /** takes a paramList element, and gets a HashMap of name-value pairs
    216      * if deep=true, extracts embedded params, otherwise just top level
    217      * params*/
    218     public static HashMap extractParams(Element xml, boolean deep) {
    219 
    220     if (!xml.getNodeName().equals(PARAM_ELEM+LIST_MODIFIER)) {
    221         logger.error("paramList element should have been passed to extractParams, instead it was "+xml.getNodeName());
    222         return null;
    223     }
    224 
    225     NodeList params = null;
    226     if (deep) { // get all the nested ones
    227         params = xml.getElementsByTagName(PARAM_ELEM);
    228     } else { // just get the top  level ones
    229         params = xml.getChildNodes();
    230     }
    231     HashMap param_map = new HashMap();
    232     for (int i=0; i<params.getLength(); i++) {
    233         if (params.item(i).getNodeName().equals(PARAM_ELEM)) {
    234         Element param = (Element)params.item(i);
    235         String name=param.getAttribute(NAME_ATT);
    236         String value=getValue(param); //att or content
    237         int pos = name.indexOf('.');
    238         if (pos == -1) { // a base param
    239             param_map.put(name, value);
    240         } else { // a namespaced param
    241            
    242             String namespace = name.substring(0, pos);
    243             name = name.substring(pos+1);
    244             HashMap map = (HashMap)param_map.get(namespace);
    245             if (map == null) {
    246             map = new HashMap();
    247             param_map.put(namespace, map);
    248             }
    249             map.put(name, value);
    250         }
    251         }
    252     }
    253     return param_map;
    254     }
    255 
    256     /** gets the value att or the text content */
    257     public static String getValue(Element e) {
    258     String val = e.getAttribute(VALUE_ATT);
    259     if (val ==null || val.equals("")) {
    260         // have to get it out of the text
    261         val=getNodeText(e);
    262 
    263     } else {
    264         // unescape the xml stuff
    265         val = unXmlSafe(val);
    266     }
    267     return val;
    268     }
    269 
    270     /** extracts the text out of a node */
    271     public static Node getNodeTextNode(Element param) {
    272     param.normalize();
    273     Node n = param.getFirstChild();
    274     while (n!=null && n.getNodeType() !=Node.TEXT_NODE) {
    275         n=n.getNextSibling();
    276     }
    277     return n;
    278     }
    279    
    280     /** extracts the text out of a node */
    281     public static String getNodeText(Element param) {
    282     Node text_node = getNodeTextNode(param);
    283     if (text_node == null) {
    284         return "";
    285     }
    286     return text_node.getNodeValue();
    287     }
    288 
    289     public static void setNodeText(Element elem, String text) {
    290     Node old_text_node = getNodeTextNode(elem);
    291     if (old_text_node != null) {
    292         elem.removeChild(old_text_node);
    293     }
    294     Text t = elem.getOwnerDocument().createTextNode(text);
    295     elem.appendChild(t);
    296     }
    297    
    298     /** add text to a document/subsection  element */
    299     public static boolean addDocText(Document owner, Element doc, String text) {
    300 
    301     Element content = owner.createElement(NODE_CONTENT_ELEM);
    302     Text t = owner.createTextNode(text);
    303     content.appendChild(t);
    304     doc.appendChild(content);
    305     return true;
    306     }
    307  
    308     /** add an error message, unknown error type */
    309     public static boolean addError(Document owner, Element doc, String text) {
    310     return addError(owner, doc, text, ERROR_TYPE_OTHER);
    311     }
    312     /** add an error message */
    313     public static boolean addError(Document owner, Element doc, String text,
    314                    String error_type) {
    315 
    316     Element content = owner.createElement(ERROR_ELEM);
    317     content.setAttribute(ERROR_TYPE_ATT, error_type);
    318     Text t = owner.createTextNode(text);
    319     content.appendChild(t);
    320     doc.appendChild(content);
    321     return true;
    322     }
    323 
    324     /** add an error message */
    325     public static boolean addError(Document owner, Element doc, Throwable error) {
    326       return addError(owner, doc, error, ERROR_TYPE_OTHER);
    327     }
    328    
    329     /** add an error message */
    330     public static boolean addError(Document owner, Element doc,
    331                    Throwable error, String error_type) {
    332     error.printStackTrace();
    333     return addError(owner, doc, error.toString(), error_type);
    334     }
    335 
    336     public static Element createMetadataParamList(Document owner, Vector meta_values) {
    337 
    338     Element meta_param_list = owner.createElement(PARAM_ELEM+LIST_MODIFIER);
    339     Iterator i = meta_values.iterator();
    340     while(i.hasNext()) {
    341         String next = (String)i.next();
    342         Element meta_param = owner.createElement(PARAM_ELEM);
    343         meta_param_list.appendChild(meta_param);
    344         meta_param.setAttribute(NAME_ATT, "metadata");
    345         meta_param.setAttribute(VALUE_ATT, next);
    346     }
    347     return meta_param_list;
    348     }
    349    
    350     /** adds a metadata elem to a list */
    351     public static boolean addMetadata(Document owner, Element list,
    352                       String meta_name, String meta_value) {
    353     if (meta_value==null || meta_value.equals("")) {
    354         return false;
    355     }
    356     Element data = owner.createElement(METADATA_ELEM);
    357     data.setAttribute(NAME_ATT, meta_name);
    358     Text t = owner.createTextNode(meta_value);
    359     data.appendChild(t);
    360     list.appendChild(data);
    361     return true;
    362 
    363     }
    364 
    365     /** copies the metadata out of teh metadataList of 'from' into
    366      * the metadataList of 'to' */
    367     public static boolean mergeMetadataLists(Node to, Node from) {
    368     Node to_meta = getChildByTagName(to, METADATA_ELEM+LIST_MODIFIER);
    369     Node from_meta = getChildByTagName(from, METADATA_ELEM+LIST_MODIFIER);
    370    
    371     if  (from_meta == null) { // nothing to copy
    372         return true;
    373     }
    374     Document to_owner = to.getOwnerDocument();
    375     Node new_from = to_owner.importNode(from_meta, true);
    376 
    377     if (to_meta == null) { // just copy the whole list
    378         to.appendChild(new_from);
    379         return true;
    380     }
    381    
    382     // copy individual elements
    383     Node child = new_from.getFirstChild();
    384     while ( child != null) {
    385         to_meta.appendChild(child);
    386         child = child.getNextSibling();
    387     }
    388     return true;
    389     }
    390    
    391     /** copies all the children from from to to */
    392     public static boolean mergeElements(Element to, Element from) {
    393 
    394     Document owner = to.getOwnerDocument();
    395     Node child = from.getFirstChild();
    396     while (child != null) {
    397         to.appendChild(owner.importNode(child, true));
    398         child = child.getNextSibling();
    399     }
    400     return true;
    401     }
    402     /** returns the (first) child element with the given name */
    403     public static Node getChildByTagName(Node n, String name) {
    404 
    405     Node child = n.getFirstChild();
    406     while (child!=null) {
    407         if (child.getNodeName().equals(name)) {
    408         return child;
    409         }
    410         child = child.getNextSibling();
    411     }
    412     return null; //not found
    413     }
    414    
    415     /** returns the (nth) child element with the given name
    416      * index numbers start at 0 */
    417     public static Node getChildByTagNameIndexed(Node n, String name, int index) {
    418     if (index == -1) {
    419         return getChildByTagName(n, name);
    420     }
    421     int count = 0;
    422     Node child = n.getFirstChild();
    423     while (child!=null) {
    424         if (child.getNodeName().equals(name)) {
    425         if (count == index) {
    426             return child;
    427         } else {
    428             count++;
    429         }
    430         }
    431         child = child.getNextSibling();
    432     }
    433     return null; //not found
    434     }
    435 
    436     /** takes an xpath type expression of the form name/name/...
    437     and returns the first node that matches, or null if not found */
    438     public static Node getNodeByPath(Node n, String path) {
    439    
    440     String link = GSPath.getFirstLink(path);
    441     path = GSPath.removeFirstLink(path);
    442     while (!link.equals("")) {
    443         n = getChildByTagName(n, link);
    444         if (n==null) {
    445         return null;
    446         }
    447         link = GSPath.getFirstLink(path);
    448         path = GSPath.removeFirstLink(path);
    449     }
    450     return n;
    451     }
    452 
    453     /** takes an xpath type expression of the form name/name/...
    454      * and returns the first node that matches, or null if not found
    455      * can include [i] indices. index numbers start at 0 */
    456     public static Node getNodeByPathIndexed(Node n, String path) {
    457    
    458     String link = GSPath.getFirstLink(path);
    459     int index = GSPath.getIndex(link);
    460     if (index != -1) {
    461         link = GSPath.removeIndex(link);
    462     }
    463     path = GSPath.removeFirstLink(path);
    464     while (!link.equals("")) {
    465         n = getChildByTagNameIndexed(n, link, index);
    466         if (n==null) {
    467         return null;
    468         }
    469         link = GSPath.getFirstLink(path);
    470         index = GSPath.getIndex(link);
    471         if (index != -1) {
    472         link = GSPath.removeIndex(link);
    473         }
    474         path = GSPath.removeFirstLink(path);
    475     }
    476     return n;
    477     }
    478 
    479     public static HashMap getChildrenMap(Node n) {
    480    
    481     HashMap map= new HashMap();
    482     Node child = n.getFirstChild();
    483     while (child!=null) {
    484         String name = child.getNodeName();
    485         map.put(name, child);
    486         child = child.getNextSibling();
    487     }
    488     return map;
    489     }
    490        
    491     public static NodeList getChildrenByTagName(Node n, String name) {
    492     MyNodeList node_list = new MyNodeList();
    493     Node child = n.getFirstChild();
    494     while (child!=null) {
    495         if (child.getNodeName().equals(name)) {
    496         node_list.addNode(child);
    497         }
    498         child = child.getNextSibling();
    499     }
    500     return node_list;
    501     }
    502    
    503 
    504     /** Duplicates an element, but gives it a new name */
    505     public static Element duplicateWithNewName(Document owner, Element element,
    506                            String element_name, boolean with_attributes)
    507     {
    508     return duplicateWithNewNameNS(owner, element, element_name, null, with_attributes);
    509     }
    510 
    511     /** Duplicates an element, but gives it a new name */
    512     public static Element duplicateWithNewNameNS(Document owner,
    513                          Element element,
    514                          String element_name,
    515                          String namespace_uri,
    516                          boolean with_attributes)
    517     {
    518     Element duplicate;
    519     if (namespace_uri == null) {
    520         duplicate = owner.createElement(element_name);
    521     } else {
    522         duplicate = owner.createElementNS(namespace_uri, element_name);
    523     }
    524     // Copy element attributes
    525     if (with_attributes) {
    526         NamedNodeMap attributes = element.getAttributes();
    527         for (int i = 0; i < attributes.getLength(); i++) {
    528         Node attribute = attributes.item(i);
    529         duplicate.setAttribute(attribute.getNodeName(), attribute.getNodeValue());
    530         }
    531     }
    532 
    533     // Copy element children
    534     NodeList children = element.getChildNodes();
    535     for (int i = 0; i < children.getLength(); i++) {
    536         Node child = children.item(i);
    537         duplicate.appendChild(owner.importNode(child, true));
    538     }
    539 
    540     return duplicate;
    541     }
    542 
    543     public static void copyAllChildren(Element to, Element from) {
    544 
    545     Document to_doc = to.getOwnerDocument();
    546     Node child = from.getFirstChild();
    547     while (child != null) {
    548         to.appendChild(to_doc.importNode(child, true));
    549         child = child.getNextSibling();
    550     }
    551     }
    552     /** returns a basic request message */
    553     public static  Element createBasicRequest(Document owner,
    554                           String request_type, String to,
    555                           String lang,
    556                           String uid) {
    557     Element request = owner.createElement(REQUEST_ELEM);
    558     request.setAttribute(TYPE_ATT, request_type);
    559     request.setAttribute(LANG_ATT, lang);
    560     request.setAttribute(TO_ATT, to);
    561     request.setAttribute(USER_ID_ATT, uid);
    562     return request;
    563     }
    564    
    565     public static Element createTextElement(Document owner, String elem_name,
    566                         String text) {
    567     Element e = owner.createElement(elem_name);
    568     Text t = owner.createTextNode(text);
    569     e.appendChild(t);
    570     return e;
    571 
    572     }
    573 
    574     public static Element createDisplayTextElement(Document owner,
    575                            String text_name,
    576                            String text) {
    577     Element e = owner.createElement(DISPLAY_TEXT_ELEM);
    578     e.setAttribute(NAME_ATT, text_name);
    579     Text t = owner.createTextNode(text);
    580     e.appendChild(t);
    581     return e;
    582 
    583     }
    584 
    585 
    586     public static Element createParameter(Document owner, String name,
    587                       String value) {
    588     Element param = owner.createElement(PARAM_ELEM);
    589     param.setAttribute(NAME_ATT, name);
    590     param.setAttribute(VALUE_ATT, value);
    591     return param;
    592     }
    593 
    594     public static void addParametersToList(Document owner, Element param_list,
    595                        HashMap params) {
    596     Set items = params.entrySet();
    597     Iterator i = items.iterator();
    598     while(i.hasNext()) {
    599         Map.Entry m = (Map.Entry)i.next();
    600         param_list.appendChild(createParameter(owner, (String)m.getKey(), (String)m.getValue()));
    601     }
    602    
    603     }
    604 
    605     public static Element createParameterDescription(Document owner,
    606                              String id,
    607                              String display_name,
    608                              String type,
    609                              String default_value,
    610                              String []option_ids,
    611                              String []option_names) {
    612 
    613    
    614     Element p = owner.createElement(PARAM_ELEM);
    615     p.setAttribute(NAME_ATT, id);
    616     p.setAttribute(TYPE_ATT, type);
    617     p.appendChild(createDisplayTextElement(owner, GSXML.DISPLAY_TEXT_NAME, display_name));
    618 
    619     if (default_value != null) {
    620         p.setAttribute(DEFAULT_ATT, default_value);
    621     }
    622     if (option_ids!=null && option_names!=null) {
    623         for (int i=0; i<option_ids.length; i++) {
    624         Element e = owner.createElement(PARAM_OPTION_ELEM);
    625         e.setAttribute(NAME_ATT, option_ids[i]);
    626         e.appendChild(createDisplayTextElement(owner, GSXML.DISPLAY_TEXT_NAME, option_names[i]));
    627         p.appendChild(e);
    628         }
    629     }
    630     return p;
    631     }
    632     public static Element createParameterDescription2(Document owner,
    633                              String id,
    634                              String display_name,
    635                              String type,
    636                              String default_value,
    637                              ArrayList option_ids,
    638                              ArrayList option_names) {
    639 
    640    
    641     Element p = owner.createElement(PARAM_ELEM);
    642     p.setAttribute(NAME_ATT, id);
    643     p.setAttribute(TYPE_ATT, type);
    644     p.appendChild(createDisplayTextElement(owner, GSXML.DISPLAY_TEXT_NAME, display_name));
    645     if (default_value != null) {
    646         p.setAttribute(DEFAULT_ATT, default_value);
    647     }
    648     if (option_ids!=null && option_names!=null) {
    649         for (int i=0; i<option_ids.size(); i++) {
    650         Element e = owner.createElement(PARAM_OPTION_ELEM);
    651         e.setAttribute(NAME_ATT, (String)option_ids.get(i));
    652         e.appendChild(createDisplayTextElement(owner, GSXML.DISPLAY_TEXT_NAME, (String)option_names.get(i)));
    653         p.appendChild(e);
    654         }
    655     }
    656     return p;
    657     }
    658 
    659 
    660     /** returns the element parent/node_name[@attribute_name='attribute_value']
    661      */
    662     public static Element getNamedElement(Element parent, String node_name,
    663                       String attribute_name,
    664                       String attribute_value) {
    665 
    666     NodeList children = parent.getChildNodes();
    667     for (int i=0; i<children.getLength(); i++) {
    668         Node child = children.item(i);
    669         if (child.getNodeName().equals(node_name)) {
    670         if (((Element)child).getAttribute(attribute_name).equals(attribute_value))
    671             return (Element)child;
    672         }
    673     }
    674     // not found
    675     return null;
    676     }
    677 
    678     public static int SORT_TYPE_STRING = 0;
    679     public static int SORT_TYPE_INT = 1;
    680     public static int SORT_TYPE_FLOAT = 2;
    681    
    682     // sort type:
    683     public static Element insertIntoOrderedList(Element parent_node,
    684                         String node_name,
    685                         Element start_from_elem,
    686                         Element new_elem, String sort_att,
    687                         boolean descending)
    688     {
    689     if (new_elem == null) return null;
    690     Element cloned_elem = (Element)parent_node.getOwnerDocument().importNode(new_elem, true);
    691     if (start_from_elem == null) {
    692         parent_node.appendChild(cloned_elem);
    693         return cloned_elem;
    694     }
    695        
    696     Node current_node = start_from_elem;
    697     String insert_att = cloned_elem.getAttribute(sort_att);
    698     String list_att = start_from_elem.getAttribute(sort_att);
    699     while ((!descending && list_att.compareTo(insert_att)<0) || (descending && list_att.compareTo(insert_att)>0)) {
    700         current_node = current_node.getNextSibling();
    701         if (current_node == null) break; // end of the list
    702         if (!current_node.getNodeName().equals(node_name)) {
    703         continue; // not a valid node
    704         }
    705         list_att = ((Element)current_node).getAttribute(sort_att);
    706     }
    707    
    708     parent_node.insertBefore(cloned_elem, current_node);
    709     return cloned_elem;
    710     }
    711 
    712 
    713     /** Returns the appropriate language element from a display elem,
    714      display is the containing element, name is the name of the element to
    715      look for, lang is the preferred language, lang_default is the fall back
    716      lang if neither lang is found, will return the first one it finds*/
    717     public static String getDisplayText(Element display, String name,
    718                     String lang, String lang_default) {
    719    
    720     String def = null;
    721     String first = null;
    722     NodeList elems = display.getElementsByTagName(DISPLAY_TEXT_ELEM);
    723     if (elems.getLength() == 0) return "";
    724     for (int i=0; i<elems.getLength(); i++) {
    725         Element e = (Element)elems.item(i);
    726         String n = e.getAttribute(NAME_ATT);
    727         if (name.equals(n)) {
    728         String l = e.getAttribute(LANG_ATT);
    729         if (lang.equals(l)) {
    730             return getNodeText(e);
    731         } else if (lang_default.equals(l)) {
    732             def = getNodeText(e);
    733         } else if (first == null) {
    734             first = getNodeText(e);
    735         }
    736         } else {
    737         continue;
    738         }
    739     }
    740 
    741     if (def != null) {
    742         return def;
    743     }
    744     if (first != null) {
    745         return first;
    746     }
    747     return "";
    748     }
    749    
    750     // replaces < > " ' & in the original with their entities
    751     public static String xmlSafe(String original) {
    752 
    753     StringBuffer filtered = new StringBuffer(original.length());
    754     char c;
    755     for (int i=0; i<original.length(); i++) {
    756         c = original.charAt(i);
    757         if (c == '>') {
    758         filtered.append("&gt;");
    759         } else if (c == '<') {
    760         filtered.append("&lt;");
    761         } else if (c == '"') {
    762         filtered.append("&quot;");
    763         } else if (c == '&') {
    764         filtered.append("&amp;");
    765         } else if (c == '\'') {
    766         filtered.append("&apos;");
    767         } else {
    768         filtered.append(c);
    769         }
    770     }
    771     return filtered.toString();
    772     }
    773 
    774    
    775     // replaces < > " ' & entities with their originals
    776     public static String unXmlSafe(String original) {
    777    
    778     StringBuffer filtered = new StringBuffer(original.length());
    779     char c;
    780     for (int i=0; i<original.length(); i++) {
    781         c = original.charAt(i);
    782         if (c == '&') {
    783         int pos = original.indexOf(";", i);
    784         String entity = original.substring(i+1, pos);
    785         if (entity.equals("gt")) {
    786             filtered.append(">");
    787         } else if (entity.equals("lt")) {
    788             filtered.append("<");
    789         } else if (entity.equals("apos")) {
    790             filtered.append("'");
    791         } else if (entity.equals("amp")) {
    792             filtered.append("&");
    793         } else if (entity.equals("quot")) {
    794             filtered.append("\"");
    795         } else {
    796             filtered.append("&"+entity+";");
    797         }
    798         i = pos;
    799         }
    800         else {
    801         filtered.append(c);
    802         }
    803     }
    804     return filtered.toString();
    805      }
    806 
    807     public static void printXMLNode(Node e) {
    808     printXMLNode(e, 0) ;
    809     }
    810 
    811     public static String xmlNodeToString(Node e){
    812         StringBuffer sb = new StringBuffer("");
    813         xmlNodeToString(sb,e,0);
    814     return sb.toString();
    815     }
    816 
    817     private static void xmlNodeToString(StringBuffer sb, Node e, int depth){
    818      
    819     for (int i=0 ; i<depth ; i++)
    820         sb.append(' ') ;
    821 
    822     if (e.getNodeType() == Node.TEXT_NODE){
    823         sb.append("text") ;
    824         return ;
    825     }
    826    
    827     sb.append('<');
    828     sb.append(e.getNodeName());
    829     NamedNodeMap attrs = e.getAttributes();
    830     for (int i = 0; i < attrs.getLength(); i++) {
    831         Node attr = attrs.item(i);
    832         sb.append(' '); 
    833         sb.append(attr.getNodeName());
    834         sb.append("=\"");
    835         sb.append(attr.getNodeValue());   
    836         sb.append('"');
    837     }
    838 
    839     NodeList children = e.getChildNodes();
    840 
    841     if (children == null || children.getLength() == 0)
    842         sb.append("/>\n") ;
    843     else {
    844        
    845         sb.append(">\n") ;
    846        
    847         int len = children.getLength();
    848         for (int i = 0; i < len; i++) {
    849         xmlNodeToString(sb,children.item(i), depth + 1);
    850         }
    851        
    852         for (int i=0 ; i<depth ; i++)
    853          sb.append(' ') ;
    854        
    855          sb.append("</" + e.getNodeName() + ">\n");
    856     }   
    857 
    858 
    859     }
    860    
    861     public static void printXMLNode(Node e, int depth) { //recursive method call using DOM API...
    862    
    863     for (int i=0 ; i<depth ; i++)
    864         System.out.print(' ') ;
    865 
    866     if (e.getNodeType() == Node.TEXT_NODE){
    867         // shouldn't we actually print the text here????
    868         System.out.println("text") ;
    869         return ;
    870     }
    871    
    872     System.out.print('<');
    873     System.out.print(e.getNodeName());
    874     NamedNodeMap attrs = e.getAttributes();
    875     for (int i = 0; i < attrs.getLength(); i++) {
    876         Node attr = attrs.item(i);
    877         System.out.print(' '); 
    878         System.out.print(attr.getNodeName());
    879         System.out.print("=\"");
    880         System.out.print(attr.getNodeValue());   
    881         System.out.print('"');
    882     }
    883 
    884     NodeList children = e.getChildNodes();
    885 
    886     if (children == null || children.getLength() == 0)
    887         System.out.println("/>") ;
    888     else {
    889        
    890         System.out.println('>') ;
    891        
    892         int len = children.getLength();
    893         for (int i = 0; i < len; i++) {
    894         printXMLNode(children.item(i), depth + 1);
    895         }
    896        
    897         for (int i=0 ; i<depth ; i++)
    898         System.out.print(' ') ;
    899        
    900         System.out.println("</" + e.getNodeName() + ">");
    901     }   
    902 
    903     }
     23 
     24  static Logger logger = Logger.getLogger(org.greenstone.gsdl3.util.GSXML.class.getName());
     25 
     26  // greenstone xml elements
     27  public static final String MESSAGE_ELEM = "message";
     28  public static final String REQUEST_ELEM = "request";
     29  public static final String RESPONSE_ELEM = "response";
     30  public static final String COLLECTION_ELEM = "collection";
     31  public static final String SERVICE_ELEM = "service";
     32  public static final String CLUSTER_ELEM = "serviceCluster";
     33  public static final String SITE_ELEM = "site";
     34  public static final String PARAM_ELEM = "param";
     35  public static final String PARAM_OPTION_ELEM = "option";
     36  public static final String CONTENT_ELEM = "content";
     37  public static final String RESOURCE_ELEM = "resource";
     38  public static final String DOCUMENT_ELEM = "document";
     39  public static final String METADATA_ELEM = "metadata";
     40  public static final String SERVICE_CLASS_ELEM = "serviceRack";
     41  public static final String CLASSIFIER_ELEM = "classifier";
     42  public static final String APPLET_ELEM = "applet";
     43  public static final String APPLET_DATA_ELEM = "appletData";
     44  public static final String CONFIGURE_ELEM = "configure";
     45  public static final String STATUS_ELEM = "status";
     46  public static final String ERROR_ELEM = "error";
     47  public static final String DEFAULT_ELEM = "default";
     48  public static final String STYLESHEET_ELEM = "format";//"stylesheet"; // any additional stylesheet stuff is carried in the message inside this elem
     49  public static final String FORMAT_ELEM = "format"; // config files use format - should we use this instead of stylesheet??
     50  public static final String TERM_ELEM = "term";
     51  public static final String SYSTEM_ELEM = "system";
     52 
     53  //config file elems
     54  public static final String COLLECTION_CONFIG_ELEM = "collectionConfig";
     55  public static final String COLLECTION_BUILD_ELEM = "buildConfig";
     56  public static final String COLLECTION_INIT_ELEM = "collectionInit";
     57  public static final String RECOGNISE_ELEM = "recognise";
     58  public static final String DOC_TYPE_ELEM = "docType";
     59  public static final String SEARCH_ELEM = "search";
     60  public static final String INDEX_ELEM = "index";
     61  public static final String INDEX_STEM_ELEM = "indexStem";
     62  public static final String INDEX_OPTION_ELEM = "indexOption";
     63  public static final String BROWSE_ELEM = "browse";
     64  public static final String DISPLAY_ELEM = "display";
     65  public static final String LEVEL_ELEM = "level";
     66  public static final String SHORTNAME_ATT = "shortname";
     67  public static final String NOTIFY_ELEM = "notify";
     68  public static final String NOTIFY_HOST_ATT = "host";
     69 
     70  // elems for the pages to be processed by xslt
     71  public final static String PAGE_ELEM = "page";
     72  public final static String CONFIGURATION_ELEM = "config";
     73  public final static String PAGE_REQUEST_ELEM = "pageRequest";
     74  public final static String PAGE_RESPONSE_ELEM = "pageResponse";
     75  public final static String PAGE_EXTRA_ELEM = "pageExtra";
     76 
     77  //public final static String DESCRIPTION_ELEM = "description";
     78 
     79  public static final String  ACTION_ELEM = "action";
     80  public static final String  SUBACTION_ELEM = "subaction";
     81 
     82  // add on to another elem type to get a list of that type
     83  public static final String LIST_MODIFIER = "List";
     84 
     85  // greenstone xml attributes
     86  public static final String NAME_ATT = "name";
     87  public static final String TO_ATT = "to";
     88  public static final String USER_ID_ATT = "uid";
     89  public static final String FROM_ATT = "from";
     90  public static final String LANG_ATT = "lang";
     91  public static final String TYPE_ATT = "type";
     92  public static final String VALUE_ATT = "value";
     93  public static final String DEFAULT_ATT = "default";
     94  public static final String INFO_ATT = "info";
     95  public static final String ACTION_ATT = "action";
     96  public static final String SUBACTION_ATT = "subaction";
     97  public static final String OUTPUT_ATT = "output";
     98  public static final String ADDRESS_ATT = "address";
     99  public static final String LOCAL_SITE_ATT = "localSite";
     100  public static final String LOCAL_SITE_NAME_ATT = "localSiteName";
     101  public static final String STATUS_ERROR_CODE_ATT = "code";
     102  public static final String STATUS_PROCESS_ID_ATT = "pid";
     103  public static final String PARAM_SHORTNAME_ATT = "shortname";
     104  public static final String PARAM_IGNORE_POS_ATT = "ignore";
     105  public static final String CLASSIFIER_CONTENT_ATT = "content";
     106  public static final String ERROR_TYPE_ATT = "type";
     107 
     108  // document stuff
     109  public static final String DOC_TYPE_ATT = "docType";
     110  public static final String DOC_NODE_ELEM = "documentNode";
     111  public static final String NODE_CONTENT_ELEM = "nodeContent";
     112  public static final String NODE_STRUCTURE_ELEM = "nodeStructure";
     113  public static final String NODE_ID_ATT = "nodeID";
     114  public static final String NODE_NAME_ATT = "nodeName";
     115  public static final String NODE_TYPE_ATT = "nodeType";
     116  public static final String NODE_RANK_ATT = "rank";
     117  public static final String NODE_TYPE_ROOT = "root";
     118  public static final String NODE_TYPE_INTERNAL = "internal";
     119  public static final String NODE_TYPE_LEAF = "leaf";
     120 
     121  public static final String DOC_TYPE_SIMPLE = "simple";
     122  public static final String DOC_TYPE_PAGED = "paged";
     123  public static final String DOC_TYPE_HIERARCHY = "hierarchy";
     124 
     125  // classifier stuff
     126  public static final String CLASS_NODE_ELEM = "classifierNode";
     127  public static final String CLASS_NODE_ORIENTATION_ATT = "orientation";
     128 
     129  // parameter types
     130  public static final String PARAM_TYPE_INTEGER = "integer";
     131  public static final String PARAM_TYPE_BOOLEAN = "boolean";
     132  public static final String PARAM_TYPE_ENUM_START = "enum";
     133  public static final String PARAM_TYPE_ENUM_SINGLE = "enum_single";
     134  public static final String PARAM_TYPE_ENUM_MULTI = "enum_multi";
     135  public static final String PARAM_TYPE_STRING = "string";
     136  public static final String PARAM_TYPE_TEXT = "text";
     137  public static final String PARAM_TYPE_MULTI = "multi";
     138  public static final String PARAM_TYPE_FILE = "file";
     139  public static final String PARAM_TYPE_INVISIBLE = "invisible";
     140  // stuff for text strings
     141  public static final String DISPLAY_TEXT_ELEM = "displayItem";
     142  // the following are used for the name attributes
     143  public static final String DISPLAY_TEXT_NAME = "name";
     144  public static final String DISPLAY_TEXT_SUBMIT = "submit";
     145  public static final String DISPLAY_TEXT_DESCRIPTION = "description";
     146 
     147  // request types
     148  // get the module description
     149  public static final String REQUEST_TYPE_DESCRIBE = "describe";
     150  // startup a process
     151  public static final String REQUEST_TYPE_PROCESS = "process";
     152  // get the status of an ongoing process
     153  public static final String REQUEST_TYPE_STATUS = "status";
     154  // system type request - eg reload a collection
     155  public static final String REQUEST_TYPE_SYSTEM = "system";
     156  // page requests to the Receptionist/Actions
     157  public static final String REQUEST_TYPE_PAGE = "page"; // used to be cgi
     158  // get any format info for a service
     159  public static final String REQUEST_TYPE_FORMAT = "format";
     160  // modify the requests
     161  public static final String REQUEST_TYPE_MESSAGING = "messaging";
     162 
     163  // service types
     164  public static final String SERVICE_TYPE_QUERY = "query";
     165  public static final String SERVICE_TYPE_RETRIEVE = "retrieve";
     166  public static final String SERVICE_TYPE_BROWSE = "browse";
     167  public static final String SERVICE_TYPE_APPLET = "applet";
     168  public static final String SERVICE_TYPE_PROCESS = "process";
     169  public static final String SERVICE_TYPE_ENRICH = "enrich";
     170 
     171  // system command types and attributes
     172  public static final String SYSTEM_TYPE_CONFIGURE = "configure";
     173  public static final String SYSTEM_TYPE_ACTIVATE = "activate";
     174  public static final String SYSTEM_TYPE_DEACTIVATE = "deactivate";
     175 
     176  public static final String SYSTEM_SUBSET_ATT = "subset";
     177  public static final String SYSTEM_MODULE_TYPE_ATT = "moduleType";
     178  public static final String SYSTEM_MODULE_NAME_ATT = "moduleName";
     179 
     180  // communicator types
     181  public static final String COMM_TYPE_SOAP_JAVA = "soap";
     182 
     183  // error types
     184  public static final String ERROR_TYPE_SYNTAX = "syntax";
     185  public static final String ERROR_TYPE_SYSTEM = "system";
     186  public static final String ERROR_TYPE_INVALID_ID = "invalid_id";
     187  public static final String ERROR_TYPE_OTHER = "other";
     188 
     189  // some system wide param names
     190  public static final String SUBSET_PARAM = "subset";
     191 
     192  //for plugin
     193  public static final String PLUGIN_ELEM = "plugin";
     194  public static final String IMPORT_ELEM = "import";
     195 
     196 
     197  /** takes a list of elements, and returns an array of strings
     198   * of the values of attribute att_name */
     199  public static String [] getAttributeValuesFromList(Element list,
     200    String att_name) {
     201   
     202    NodeList children = list.getChildNodes();
     203   
     204    int num_nodes = children.getLength();
     205    String []ids = new String[num_nodes];
     206    for (int i=0; i<num_nodes; i++) {
     207      Element e = (Element)children.item(i);
     208      String id = e.getAttribute(att_name);
     209      ids[i] = id;
     210    }
     211   
     212    return ids;
     213  }
     214 
     215  /** takes a paramList element, and gets a HashMap of name-value pairs
     216   * if deep=true, extracts embedded params, otherwise just top level
     217   * params*/
     218  public static HashMap extractParams(Element xml, boolean deep) {
     219   
     220    if (!xml.getNodeName().equals(PARAM_ELEM+LIST_MODIFIER)) {
     221      logger.error("paramList element should have been passed to extractParams, instead it was "+xml.getNodeName());
     222      return null;
     223    }
     224   
     225    NodeList params = null;
     226    if (deep) { // get all the nested ones
     227      params = xml.getElementsByTagName(PARAM_ELEM);
     228    } else { // just get the top  level ones
     229      params = xml.getChildNodes();
     230    }
     231    HashMap param_map = new HashMap();
     232    for (int i=0; i<params.getLength(); i++) {
     233      if (params.item(i).getNodeName().equals(PARAM_ELEM)) {
     234        Element param = (Element)params.item(i);
     235        String name=param.getAttribute(NAME_ATT);
     236        String value=getValue(param); //att or content
     237        int pos = name.indexOf('.');
     238        if (pos == -1) { // a base param
     239          param_map.put(name, value);
     240        } else { // a namespaced param
     241         
     242          String namespace = name.substring(0, pos);
     243          name = name.substring(pos+1);
     244          HashMap map = (HashMap)param_map.get(namespace);
     245          if (map == null) {
     246            map = new HashMap();
     247            param_map.put(namespace, map);
     248          }
     249          map.put(name, value);
     250        }
     251      }
     252    }
     253    return param_map;
     254  }
     255 
     256  /** gets the value att or the text content */
     257  public static String getValue(Element e) {
     258    String val = e.getAttribute(VALUE_ATT);
     259    if (val ==null || val.equals("")) {
     260      // have to get it out of the text
     261      val=getNodeText(e);
     262     
     263    } else {
     264      // unescape the xml stuff
     265      val = unXmlSafe(val);
     266    }
     267    return val;
     268  }
     269 
     270  /** extracts the text out of a node */
     271  public static Node getNodeTextNode(Element param) {
     272    param.normalize();
     273    Node n = param.getFirstChild();
     274    while (n!=null && n.getNodeType() !=Node.TEXT_NODE) {
     275      n=n.getNextSibling();
     276    }
     277    return n;
     278  }
     279 
     280  /** extracts the text out of a node */
     281  public static String getNodeText(Element param) {
     282    Node text_node = getNodeTextNode(param);
     283    if (text_node == null) {
     284      return "";
     285    }
     286    return text_node.getNodeValue();
     287  }
     288 
     289  public static void setNodeText(Element elem, String text) {
     290    Node old_text_node = getNodeTextNode(elem);
     291    if (old_text_node != null) {
     292      elem.removeChild(old_text_node);
     293    }
     294    Text t = elem.getOwnerDocument().createTextNode(text);
     295    elem.appendChild(t);
     296  }
     297 
     298  /** add text to a document/subsection  element */
     299  public static boolean addDocText(Document owner, Element doc, String text) {
     300   
     301    Element content = owner.createElement(NODE_CONTENT_ELEM);
     302    Text t = owner.createTextNode(text);
     303    content.appendChild(t);
     304    doc.appendChild(content);
     305    return true;
     306  }
     307 
     308  /** add an error message, unknown error type */
     309  public static boolean addError(Document owner, Element doc, String text) {
     310    return addError(owner, doc, text, ERROR_TYPE_OTHER);
     311  }
     312  /** add an error message */
     313  public static boolean addError(Document owner, Element doc, String text,
     314    String error_type) {
     315   
     316    Element content = owner.createElement(ERROR_ELEM);
     317    content.setAttribute(ERROR_TYPE_ATT, error_type);
     318    Text t = owner.createTextNode(text);
     319    content.appendChild(t);
     320    doc.appendChild(content);
     321    return true;
     322  }
     323 
     324  /** add an error message */
     325  public static boolean addError(Document owner, Element doc, Throwable error) {
     326    return addError(owner, doc, error, ERROR_TYPE_OTHER);
     327  }
     328 
     329  /** add an error message */
     330  public static boolean addError(Document owner, Element doc,
     331    Throwable error, String error_type) {
     332    error.printStackTrace();
     333    return addError(owner, doc, error.toString(), error_type);
     334  }
     335 
     336  public static Element createMetadataParamList(Document owner, Vector meta_values) {
     337   
     338    Element meta_param_list = owner.createElement(PARAM_ELEM+LIST_MODIFIER);
     339    Iterator i = meta_values.iterator();
     340    while(i.hasNext()) {
     341      String next = (String)i.next();
     342      Element meta_param = owner.createElement(PARAM_ELEM);
     343      meta_param_list.appendChild(meta_param);
     344      meta_param.setAttribute(NAME_ATT, "metadata");
     345      meta_param.setAttribute(VALUE_ATT, next);
     346    }
     347    return meta_param_list;
     348  }
     349 
     350  /** adds a metadata elem to a list */
     351  public static boolean addMetadata(Document owner, Element list,
     352    String meta_name, String meta_value) {
     353    if (meta_value==null || meta_value.equals("")) {
     354      return false;
     355    }
     356    Element data = owner.createElement(METADATA_ELEM);
     357    data.setAttribute(NAME_ATT, meta_name);
     358    Text t = owner.createTextNode(meta_value);
     359    data.appendChild(t);
     360    list.appendChild(data);
     361    return true;
     362   
     363  }
     364 
     365  /** copies the metadata out of teh metadataList of 'from' into
     366   * the metadataList of 'to' */
     367  public static boolean mergeMetadataLists(Node to, Node from) {
     368    Node to_meta = getChildByTagName(to, METADATA_ELEM+LIST_MODIFIER);
     369    Node from_meta = getChildByTagName(from, METADATA_ELEM+LIST_MODIFIER);
     370   
     371    if  (from_meta == null) { // nothing to copy
     372      return true;
     373    }
     374    Document to_owner = to.getOwnerDocument();
     375    Node new_from = to_owner.importNode(from_meta, true);
     376   
     377    if (to_meta == null) { // just copy the whole list
     378      to.appendChild(new_from);
     379      return true;
     380    }
     381   
     382    // copy individual elements
     383    Node child = new_from.getFirstChild();
     384    while ( child != null) {
     385      to_meta.appendChild(child);
     386      child = child.getNextSibling();
     387    }
     388    return true;
     389  }
     390 
     391  /** copies all the children from from to to */
     392  public static boolean mergeElements(Element to, Element from) {
     393   
     394    Document owner = to.getOwnerDocument();
     395    Node child = from.getFirstChild();
     396    while (child != null) {
     397      to.appendChild(owner.importNode(child, true));
     398      child = child.getNextSibling();
     399    }
     400    return true;
     401  }
     402  /** returns the (first) element child of the node n */
     403  public static Element getFirstElementChild(Node n) {
     404   
     405    Node child = n.getFirstChild();
     406    while (child!=null) {
     407      if (child.getNodeType() == Node.ELEMENT_NODE) {
     408        return (Element)child;
     409      }
     410      child = child.getNextSibling();
     411    }
     412    return null; //no element child found
     413  }
     414  /** returns the (first) child element with the given name */
     415  public static Node getChildByTagName(Node n, String name) {
     416   
     417    Node child = n.getFirstChild();
     418    while (child!=null) {
     419      if (child.getNodeName().equals(name)) {
     420        return child;
     421      }
     422      child = child.getNextSibling();
     423    }
     424    return null; //not found
     425  }
     426 
     427  /** returns the (nth) child element with the given name
     428   * index numbers start at 0 */
     429  public static Node getChildByTagNameIndexed(Node n, String name, int index) {
     430    if (index == -1) {
     431      return getChildByTagName(n, name);
     432    }
     433    int count = 0;
     434    Node child = n.getFirstChild();
     435    while (child!=null) {
     436      if (child.getNodeName().equals(name)) {
     437        if (count == index) {
     438          return child;
     439        } else {
     440          count++;
     441        }
     442      }
     443      child = child.getNextSibling();
     444    }
     445    return null; //not found
     446  }
     447 
     448  /** takes an xpath type expression of the form name/name/...
     449   * and returns the first node that matches, or null if not found */
     450  public static Node getNodeByPath(Node n, String path) {
     451   
     452    String link = GSPath.getFirstLink(path);
     453    path = GSPath.removeFirstLink(path);
     454    while (!link.equals("")) {
     455      n = getChildByTagName(n, link);
     456      if (n==null) {
     457        return null;
     458      }
     459      link = GSPath.getFirstLink(path);
     460      path = GSPath.removeFirstLink(path);
     461    }
     462    return n;
     463  }
     464 
     465  /** takes an xpath type expression of the form name/name/...
     466   * and returns the first node that matches, or null if not found
     467   * can include [i] indices. index numbers start at 0 */
     468  public static Node getNodeByPathIndexed(Node n, String path) {
     469   
     470    String link = GSPath.getFirstLink(path);
     471    int index = GSPath.getIndex(link);
     472    if (index != -1) {
     473      link = GSPath.removeIndex(link);
     474    }
     475    path = GSPath.removeFirstLink(path);
     476    while (!link.equals("")) {
     477      n = getChildByTagNameIndexed(n, link, index);
     478      if (n==null) {
     479        return null;
     480      }
     481      link = GSPath.getFirstLink(path);
     482      index = GSPath.getIndex(link);
     483      if (index != -1) {
     484        link = GSPath.removeIndex(link);
     485      }
     486      path = GSPath.removeFirstLink(path);
     487    }
     488    return n;
     489  }
     490 
     491  public static HashMap getChildrenMap(Node n) {
     492   
     493    HashMap map= new HashMap();
     494    Node child = n.getFirstChild();
     495    while (child!=null) {
     496      String name = child.getNodeName();
     497      map.put(name, child);
     498      child = child.getNextSibling();
     499    }
     500    return map;
     501  }
     502 
     503  public static NodeList getChildrenByTagName(Node n, String name) {
     504    MyNodeList node_list = new MyNodeList();
     505    Node child = n.getFirstChild();
     506    while (child!=null) {
     507      if (child.getNodeName().equals(name)) {
     508        node_list.addNode(child);
     509      }
     510      child = child.getNextSibling();
     511    }
     512    return node_list;
     513  }
     514 
     515 
     516  /** Duplicates an element, but gives it a new name */
     517  public static Element duplicateWithNewName(Document owner, Element element,
     518    String element_name, boolean with_attributes) {
     519    return duplicateWithNewNameNS(owner, element, element_name, null, with_attributes);
     520  }
     521 
     522  /** Duplicates an element, but gives it a new name */
     523  public static Element duplicateWithNewNameNS(Document owner,
     524    Element element,
     525    String element_name,
     526    String namespace_uri,
     527    boolean with_attributes) {
     528    Element duplicate;
     529    if (namespace_uri == null) {
     530      duplicate = owner.createElement(element_name);
     531    } else {
     532      duplicate = owner.createElementNS(namespace_uri, element_name);
     533    }
     534    // Copy element attributes
     535    if (with_attributes) {
     536      NamedNodeMap attributes = element.getAttributes();
     537      for (int i = 0; i < attributes.getLength(); i++) {
     538        Node attribute = attributes.item(i);
     539        duplicate.setAttribute(attribute.getNodeName(), attribute.getNodeValue());
     540      }
     541    }
     542   
     543    // Copy element children
     544    NodeList children = element.getChildNodes();
     545    for (int i = 0; i < children.getLength(); i++) {
     546      Node child = children.item(i);
     547      duplicate.appendChild(owner.importNode(child, true));
     548    }
     549   
     550    return duplicate;
     551  }
     552 
     553  public static void copyAllChildren(Element to, Element from) {
     554   
     555    Document to_doc = to.getOwnerDocument();
     556    Node child = from.getFirstChild();
     557    while (child != null) {
     558      to.appendChild(to_doc.importNode(child, true));
     559      child = child.getNextSibling();
     560    }
     561  }
     562  /** returns a basic request message */
     563  public static  Element createBasicRequest(Document owner,
     564    String request_type, String to,
     565    String lang,
     566    String uid) {
     567    Element request = owner.createElement(REQUEST_ELEM);
     568    request.setAttribute(TYPE_ATT, request_type);
     569    request.setAttribute(LANG_ATT, lang);
     570    request.setAttribute(TO_ATT, to);
     571    request.setAttribute(USER_ID_ATT, uid);
     572    return request;
     573  }
     574 
     575  public static Element createTextElement(Document owner, String elem_name,
     576    String text) {
     577    Element e = owner.createElement(elem_name);
     578    Text t = owner.createTextNode(text);
     579    e.appendChild(t);
     580    return e;
     581   
     582  }
     583 
     584  public static Element createDisplayTextElement(Document owner,
     585    String text_name,
     586    String text) {
     587    Element e = owner.createElement(DISPLAY_TEXT_ELEM);
     588    e.setAttribute(NAME_ATT, text_name);
     589    Text t = owner.createTextNode(text);
     590    e.appendChild(t);
     591    return e;
     592   
     593  }
     594 
     595 
     596  public static Element createParameter(Document owner, String name,
     597    String value) {
     598    Element param = owner.createElement(PARAM_ELEM);
     599    param.setAttribute(NAME_ATT, name);
     600    param.setAttribute(VALUE_ATT, value);
     601    return param;
     602  }
     603 
     604  public static void addParametersToList(Document owner, Element param_list,
     605    HashMap params) {
     606    Set items = params.entrySet();
     607    Iterator i = items.iterator();
     608    while(i.hasNext()) {
     609      Map.Entry m = (Map.Entry)i.next();
     610      param_list.appendChild(createParameter(owner, (String)m.getKey(), (String)m.getValue()));
     611    }
     612   
     613  }
     614 
     615  public static Element createParameterDescription(Document owner,
     616    String id,
     617    String display_name,
     618    String type,
     619    String default_value,
     620    String []option_ids,
     621    String []option_names) {
     622   
     623   
     624    Element p = owner.createElement(PARAM_ELEM);
     625    p.setAttribute(NAME_ATT, id);
     626    p.setAttribute(TYPE_ATT, type);
     627    p.appendChild(createDisplayTextElement(owner, GSXML.DISPLAY_TEXT_NAME, display_name));
     628   
     629    if (default_value != null) {
     630      p.setAttribute(DEFAULT_ATT, default_value);
     631    }
     632    if (option_ids!=null && option_names!=null) {
     633      for (int i=0; i<option_ids.length; i++) {
     634        Element e = owner.createElement(PARAM_OPTION_ELEM);
     635        e.setAttribute(NAME_ATT, option_ids[i]);
     636        e.appendChild(createDisplayTextElement(owner, GSXML.DISPLAY_TEXT_NAME, option_names[i]));
     637        p.appendChild(e);
     638      }
     639    }
     640    return p;
     641  }
     642  public static Element createParameterDescription2(Document owner,
     643    String id,
     644    String display_name,
     645    String type,
     646    String default_value,
     647    ArrayList option_ids,
     648    ArrayList option_names) {
     649   
     650   
     651    Element p = owner.createElement(PARAM_ELEM);
     652    p.setAttribute(NAME_ATT, id);
     653    p.setAttribute(TYPE_ATT, type);
     654    p.appendChild(createDisplayTextElement(owner, GSXML.DISPLAY_TEXT_NAME, display_name));
     655    if (default_value != null) {
     656      p.setAttribute(DEFAULT_ATT, default_value);
     657    }
     658    if (option_ids!=null && option_names!=null) {
     659      for (int i=0; i<option_ids.size(); i++) {
     660        Element e = owner.createElement(PARAM_OPTION_ELEM);
     661        e.setAttribute(NAME_ATT, (String)option_ids.get(i));
     662        e.appendChild(createDisplayTextElement(owner, GSXML.DISPLAY_TEXT_NAME, (String)option_names.get(i)));
     663        p.appendChild(e);
     664      }
     665    }
     666    return p;
     667  }
     668 
     669 
     670  /** returns the element parent/node_name[@attribute_name='attribute_value']
     671   */
     672  public static Element getNamedElement(Element parent, String node_name,
     673    String attribute_name,
     674    String attribute_value) {
     675   
     676    NodeList children = parent.getChildNodes();
     677    for (int i=0; i<children.getLength(); i++) {
     678      Node child = children.item(i);
     679      if (child.getNodeName().equals(node_name)) {
     680        if (((Element)child).getAttribute(attribute_name).equals(attribute_value))
     681          return (Element)child;
     682      }
     683    }
     684    // not found
     685    return null;
     686  }
     687 
     688  public static int SORT_TYPE_STRING = 0;
     689  public static int SORT_TYPE_INT = 1;
     690  public static int SORT_TYPE_FLOAT = 2;
     691 
     692  // sort type:
     693  public static Element insertIntoOrderedList(Element parent_node,
     694    String node_name,
     695    Element start_from_elem,
     696    Element new_elem, String sort_att,
     697    boolean descending) {
     698    if (new_elem == null) return null;
     699    Element cloned_elem = (Element)parent_node.getOwnerDocument().importNode(new_elem, true);
     700    if (start_from_elem == null) {
     701      parent_node.appendChild(cloned_elem);
     702      return cloned_elem;
     703    }
     704   
     705    Node current_node = start_from_elem;
     706    String insert_att = cloned_elem.getAttribute(sort_att);
     707    String list_att = start_from_elem.getAttribute(sort_att);
     708    while ((!descending && list_att.compareTo(insert_att)<0) || (descending && list_att.compareTo(insert_att)>0)) {
     709      current_node = current_node.getNextSibling();
     710      if (current_node == null) break; // end of the list
     711      if (!current_node.getNodeName().equals(node_name)) {
     712        continue; // not a valid node
     713      }
     714      list_att = ((Element)current_node).getAttribute(sort_att);
     715    }
     716   
     717    parent_node.insertBefore(cloned_elem, current_node);
     718    return cloned_elem;
     719  }
     720 
     721 
     722  /** Returns the appropriate language element from a display elem,
     723   * display is the containing element, name is the name of the element to
     724   * look for, lang is the preferred language, lang_default is the fall back
     725   * lang if neither lang is found, will return the first one it finds*/
     726  public static String getDisplayText(Element display, String name,
     727    String lang, String lang_default) {
     728   
     729    String def = null;
     730    String first = null;
     731    NodeList elems = display.getElementsByTagName(DISPLAY_TEXT_ELEM);
     732    if (elems.getLength() == 0) return "";
     733    for (int i=0; i<elems.getLength(); i++) {
     734      Element e = (Element)elems.item(i);
     735      String n = e.getAttribute(NAME_ATT);
     736      if (name.equals(n)) {
     737        String l = e.getAttribute(LANG_ATT);
     738        if (lang.equals(l)) {
     739          return getNodeText(e);
     740        } else if (lang_default.equals(l)) {
     741          def = getNodeText(e);
     742        } else if (first == null) {
     743          first = getNodeText(e);
     744        }
     745      } else {
     746        continue;
     747      }
     748    }
     749   
     750    if (def != null) {
     751      return def;
     752    }
     753    if (first != null) {
     754      return first;
     755    }
     756    return "";
     757  }
     758 
     759  // replaces < > " ' & in the original with their entities
     760  public static String xmlSafe(String original) {
     761   
     762    StringBuffer filtered = new StringBuffer(original.length());
     763    char c;
     764    for (int i=0; i<original.length(); i++) {
     765      c = original.charAt(i);
     766      if (c == '>') {
     767        filtered.append("&gt;");
     768      } else if (c == '<') {
     769        filtered.append("&lt;");
     770      } else if (c == '"') {
     771        filtered.append("&quot;");
     772      } else if (c == '&') {
     773        filtered.append("&amp;");
     774      } else if (c == '\'') {
     775        filtered.append("&apos;");
     776      } else {
     777        filtered.append(c);
     778      }
     779    }
     780    return filtered.toString();
     781  }
     782 
     783 
     784  // replaces < > " ' & entities with their originals
     785  public static String unXmlSafe(String original) {
     786   
     787    StringBuffer filtered = new StringBuffer(original.length());
     788    char c;
     789    for (int i=0; i<original.length(); i++) {
     790      c = original.charAt(i);
     791      if (c == '&') {
     792        int pos = original.indexOf(";", i);
     793        String entity = original.substring(i+1, pos);
     794        if (entity.equals("gt")) {
     795          filtered.append(">");
     796        } else if (entity.equals("lt")) {
     797          filtered.append("<");
     798        } else if (entity.equals("apos")) {
     799          filtered.append("'");
     800        } else if (entity.equals("amp")) {
     801          filtered.append("&");
     802        } else if (entity.equals("quot")) {
     803          filtered.append("\"");
     804        } else {
     805          filtered.append("&"+entity+";");
     806        }
     807        i = pos;
     808      } else {
     809        filtered.append(c);
     810      }
     811    }
     812    return filtered.toString();
     813  }
     814 
     815  public static void printXMLNode(Node e) {
     816    printXMLNode(e, 0) ;
     817  }
     818 
     819  public static String xmlNodeToString(Node e){
     820    StringBuffer sb = new StringBuffer("");
     821    xmlNodeToString(sb,e,0);
     822    return sb.toString();
     823  }
     824 
     825  private static void xmlNodeToString(StringBuffer sb, Node e, int depth){
     826   
     827    for (int i=0 ; i<depth ; i++)
     828      sb.append(' ') ;
     829   
     830    if (e.getNodeType() == Node.TEXT_NODE){
     831      sb.append("text") ;
     832      return ;
     833    }
     834   
     835    sb.append('<');
     836    sb.append(e.getNodeName());
     837    NamedNodeMap attrs = e.getAttributes();
     838    for (int i = 0; i < attrs.getLength(); i++) {
     839      Node attr = attrs.item(i);
     840      sb.append(' ');
     841      sb.append(attr.getNodeName());
     842      sb.append("=\"");
     843      sb.append(attr.getNodeValue());
     844      sb.append('"');
     845    }
     846   
     847    NodeList children = e.getChildNodes();
     848   
     849    if (children == null || children.getLength() == 0)
     850      sb.append("/>\n") ;
     851    else {
     852     
     853      sb.append(">\n") ;
     854     
     855      int len = children.getLength();
     856      for (int i = 0; i < len; i++) {
     857        xmlNodeToString(sb,children.item(i), depth + 1);
     858      }
     859     
     860      for (int i=0 ; i<depth ; i++)
     861        sb.append(' ') ;
     862     
     863      sb.append("</" + e.getNodeName() + ">\n");
     864    }
     865   
     866   
     867  }
     868 
     869  public static void printXMLNode(Node e, int depth) { //recursive method call using DOM API...
     870   
     871    for (int i=0 ; i<depth ; i++)
     872      System.out.print(' ') ;
     873   
     874    if (e.getNodeType() == Node.TEXT_NODE){
     875      // shouldn't we actually print the text here????
     876      System.out.println("text") ;
     877      return ;
     878    }
     879   
     880    System.out.print('<');
     881    System.out.print(e.getNodeName());
     882    NamedNodeMap attrs = e.getAttributes();
     883    for (int i = 0; i < attrs.getLength(); i++) {
     884      Node attr = attrs.item(i);
     885      System.out.print(' ');
     886      System.out.print(attr.getNodeName());
     887      System.out.print("=\"");
     888      System.out.print(attr.getNodeValue());
     889      System.out.print('"');
     890    }
     891   
     892    NodeList children = e.getChildNodes();
     893   
     894    if (children == null || children.getLength() == 0)
     895      System.out.println("/>") ;
     896    else {
     897     
     898      System.out.println('>') ;
     899     
     900      int len = children.getLength();
     901      for (int i = 0; i < len; i++) {
     902        printXMLNode(children.item(i), depth + 1);
     903      }
     904     
     905      for (int i=0 ; i<depth ; i++)
     906        System.out.print(' ') ;
     907     
     908      System.out.println("</" + e.getNodeName() + ">");
     909    }
     910   
     911  }
    904912}
Note: See TracChangeset for help on using the changeset viewer.