Changeset 25688

Show
Ignore:
Timestamp:
29.05.2012 10:28:49 (7 years ago)
Author:
sjm84
Message:

Reformatting this file

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/AbstractBrowse.java

    r25635 r25688  
    1919package org.greenstone.gsdl3.service; 
    2020 
    21  
    2221// Greenstone classes 
    2322import org.greenstone.gsdl3.util.GSXML; 
     
    2827// XML classes 
    2928import org.w3c.dom.Document; 
    30 import org.w3c.dom.Element;  
     29import org.w3c.dom.Element; 
    3130import org.w3c.dom.NodeList; 
    3231 
     
    3635import org.apache.log4j.*; 
    3736 
    38 /** Partially implements a generic classifier service 
    39  * 
     37/** 
     38 * Partially implements a generic classifier service 
     39 *  
    4040 */ 
    41 public abstract class AbstractBrowse 
    42     extends ServiceRack { 
    43  
    44      static Logger logger = Logger.getLogger(org.greenstone.gsdl3.service.AbstractBrowse.class.getName()); 
    45  
    46     // the browsing services 
    47     private static final String CLASSIFIER_SERVICE = "ClassifierBrowse"; 
    48     private static final String CLASSIFIER_METADATA_SERVICE = "ClassifierBrowseMetadataRetrieve"; 
    49  
    50     // do we want to keep info request? 
    51      
    52     protected static final String STRUCT_PARAM = "structure"; 
    53     protected static final String INFO_PARAM = "info"; 
    54      
    55     protected static final String STRUCT_ANCESTORS = "ancestors"; 
    56     protected static final String STRUCT_PARENT = "parent"; 
    57     protected static final String STRUCT_SIBS = "siblings"; 
    58     protected static final String STRUCT_CHILDREN = "children"; 
    59     protected static final String STRUCT_DESCENDS = "descendants"; 
    60     protected static final String STRUCT_ENTIRE = "entire"; 
    61  
    62     protected static final String INFO_NUM_SIBS = "numSiblings"; 
    63     protected static final String INFO_NUM_CHILDREN = "numChildren"; 
    64     protected static final String INFO_SIB_POS = "siblingPosition"; 
    65  
    66     protected Element config_info = null; // the xml from the config file 
    67  
    68     protected MacroResolver macro_resolver = null; 
    69  
    70     protected String default_document_type = null; 
    71     /** constructor */ 
    72     protected AbstractBrowse() 
    73     { 
    74     } 
    75  
    76  
    77     /** configure this service */ 
    78     public boolean configure(Element info, Element extra_info) 
    79     { 
    80     if (!super.configure(info, extra_info)){ 
    81         return false; 
    82     } 
    83  
    84     logger.info("Configuring AbstractBrowse..."); 
    85     this.config_info = info; 
    86         if (macro_resolver != null) { 
    87         macro_resolver.setSiteDetails(this.site_http_address, this.cluster_name, this.library_name); 
    88         // set up the macro resolver 
    89         Element replacement_elem = (Element)GSXML.getChildByTagName(extra_info, GSXML.REPLACE_ELEM+GSXML.LIST_MODIFIER); 
    90         if (replacement_elem != null) { 
    91         macro_resolver.addMacros(replacement_elem); 
    92         } 
    93  
    94     } 
    95   
    96         // check that there are classifiers specified 
    97         Element class_list = (Element)GSXML.getChildByTagName(info, GSXML.CLASSIFIER_ELEM+GSXML.LIST_MODIFIER); 
    98         if (class_list == null) { 
    99             // no classifiers specified 
    100             return false; 
    101         } 
    102  
    103     // get the display and format elements from the coll config file for 
    104     // the classifiers 
    105     extractExtraClassifierInfo(info, extra_info); 
    106  
    107         // short_service_info_ - the browse one 
    108         Element cb_service = this.doc.createElement(GSXML.SERVICE_ELEM); 
    109         cb_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BROWSE); 
    110         cb_service.setAttribute(GSXML.NAME_ATT, CLASSIFIER_SERVICE); 
    111         this.short_service_info.appendChild(cb_service); 
    112      
    113     // metadata retrieval for the browsing   
    114         Element cbmr_service = this.doc.createElement(GSXML.SERVICE_ELEM); 
    115         cbmr_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE); 
    116         cbmr_service.setAttribute(GSXML.NAME_ATT, CLASSIFIER_METADATA_SERVICE); 
    117         this.short_service_info.appendChild(cbmr_service); 
    118  
    119     // the format info 
    120     Element cb_format_info = this.doc.createElement(GSXML.FORMAT_ELEM); 
    121     boolean format_found = false; 
    122  
    123     // try the default format first 
    124     Element def_format = (Element) GSXML.getChildByTagName(info, GSXML.FORMAT_ELEM); 
    125     if (def_format != null) { 
    126         cb_format_info.appendChild(GSXML.duplicateWithNewName(this.doc, def_format, GSXML.DEFAULT_ELEM, true)); 
    127         format_found = true; 
    128     } 
    129      
    130     // add in to the description a simplified list of classifiers 
    131         NodeList classifiers = class_list.getElementsByTagName(GSXML.CLASSIFIER_ELEM); 
    132     for(int i=0; i<classifiers.getLength(); i++) { 
    133         Element cl = (Element)classifiers.item(i); 
    134         Element new_cl = (Element)this.doc.importNode(cl, false); // just import this node, not the children 
    135          
    136         // get the format info out, and put inside a classifier element 
    137         Element format_cl = (Element)new_cl.cloneNode(false); 
    138         Element format = (Element)GSXML.getChildByTagName(cl, GSXML.FORMAT_ELEM); 
    139         if (format != null) { 
    140          
    141         //copy all the children 
    142         NodeList elems = format.getChildNodes(); 
    143         for (int j=0; j<elems.getLength();j++) { 
    144             format_cl.appendChild(this.doc.importNode(elems.item(j), true)); 
    145         } 
    146         cb_format_info.appendChild(format_cl); 
    147         format_found = true; 
    148         } 
    149                  
    150     } 
    151          
    152     if (format_found) { 
    153         this.format_info_map.put(CLASSIFIER_SERVICE, cb_format_info); 
    154     } 
    155  
    156     // look for document display format - is there a default doc type?? 
    157     String path = GSPath.appendLink(GSXML.DISPLAY_ELEM, GSXML.FORMAT_ELEM); 
    158     Element display_format = (Element)GSXML.getNodeByPath(extra_info, path); 
    159     if (display_format != null) { 
    160         // check for docType option. 
    161         Element doc_type_opt = GSXML.getNamedElement(display_format, "gsf:option", GSXML.NAME_ATT, "documentType"); 
    162         if (doc_type_opt != null) { 
    163         String value = doc_type_opt.getAttribute(GSXML.VALUE_ATT); 
    164         if (!value.equals("")) { 
    165             this.default_document_type = value; 
    166         } 
    167         } 
    168     } 
    169  
    170     return true; 
    171     } 
    172  
    173     protected Element getServiceDescription(String service_id, String lang, String subset) { 
    174  
    175     if (service_id.equals(CLASSIFIER_SERVICE)) { 
    176          
    177         Element class_list = (Element)GSXML.getChildByTagName(this.config_info, GSXML.CLASSIFIER_ELEM+GSXML.LIST_MODIFIER); 
    178         if (class_list == null) { 
    179             // no classifiers specified 
     41public abstract class AbstractBrowse extends ServiceRack 
     42{ 
     43 
     44    static Logger logger = Logger.getLogger(org.greenstone.gsdl3.service.AbstractBrowse.class.getName()); 
     45 
     46    // the browsing services 
     47    private static final String CLASSIFIER_SERVICE = "ClassifierBrowse"; 
     48    private static final String CLASSIFIER_METADATA_SERVICE = "ClassifierBrowseMetadataRetrieve"; 
     49 
     50    // do we want to keep info request? 
     51 
     52    protected static final String STRUCT_PARAM = "structure"; 
     53    protected static final String INFO_PARAM = "info"; 
     54 
     55    protected static final String STRUCT_ANCESTORS = "ancestors"; 
     56    protected static final String STRUCT_PARENT = "parent"; 
     57    protected static final String STRUCT_SIBS = "siblings"; 
     58    protected static final String STRUCT_CHILDREN = "children"; 
     59    protected static final String STRUCT_DESCENDS = "descendants"; 
     60    protected static final String STRUCT_ENTIRE = "entire"; 
     61 
     62    protected static final String INFO_NUM_SIBS = "numSiblings"; 
     63    protected static final String INFO_NUM_CHILDREN = "numChildren"; 
     64    protected static final String INFO_SIB_POS = "siblingPosition"; 
     65 
     66    protected Element config_info = null; // the xml from the config file 
     67 
     68    protected MacroResolver macro_resolver = null; 
     69 
     70    protected String default_document_type = null; 
     71 
     72    /** constructor */ 
     73    protected AbstractBrowse() 
     74    { 
     75    } 
     76 
     77    /** configure this service */ 
     78    public boolean configure(Element info, Element extra_info) 
     79    { 
     80        if (!super.configure(info, extra_info)) 
     81        { 
     82            return false; 
     83        } 
     84 
     85        logger.info("Configuring AbstractBrowse..."); 
     86        this.config_info = info; 
     87        if (macro_resolver != null) 
     88        { 
     89            macro_resolver.setSiteDetails(this.site_http_address, this.cluster_name, this.library_name); 
     90            // set up the macro resolver 
     91            Element replacement_elem = (Element) GSXML.getChildByTagName(extra_info, GSXML.REPLACE_ELEM + GSXML.LIST_MODIFIER); 
     92            if (replacement_elem != null) 
     93            { 
     94                macro_resolver.addMacros(replacement_elem); 
     95            } 
     96 
     97        } 
     98 
     99        // check that there are classifiers specified 
     100        Element class_list = (Element) GSXML.getChildByTagName(info, GSXML.CLASSIFIER_ELEM + GSXML.LIST_MODIFIER); 
     101        if (class_list == null) 
     102        { 
     103            // no classifiers specified 
     104            return false; 
     105        } 
     106 
     107        // get the display and format elements from the coll config file for 
     108        // the classifiers 
     109        extractExtraClassifierInfo(info, extra_info); 
     110 
     111        // short_service_info_ - the browse one 
     112        Element cb_service = this.doc.createElement(GSXML.SERVICE_ELEM); 
     113        cb_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BROWSE); 
     114        cb_service.setAttribute(GSXML.NAME_ATT, CLASSIFIER_SERVICE); 
     115        this.short_service_info.appendChild(cb_service); 
     116 
     117        // metadata retrieval for the browsing   
     118        Element cbmr_service = this.doc.createElement(GSXML.SERVICE_ELEM); 
     119        cbmr_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE); 
     120        cbmr_service.setAttribute(GSXML.NAME_ATT, CLASSIFIER_METADATA_SERVICE); 
     121        this.short_service_info.appendChild(cbmr_service); 
     122 
     123        // the format info 
     124        Element cb_format_info = this.doc.createElement(GSXML.FORMAT_ELEM); 
     125        boolean format_found = false; 
     126 
     127        // try the default format first 
     128        Element def_format = (Element) GSXML.getChildByTagName(info, GSXML.FORMAT_ELEM); 
     129        if (def_format != null) 
     130        { 
     131            cb_format_info.appendChild(GSXML.duplicateWithNewName(this.doc, def_format, GSXML.DEFAULT_ELEM, true)); 
     132            format_found = true; 
     133        } 
     134 
     135        // add in to the description a simplified list of classifiers 
     136        NodeList classifiers = class_list.getElementsByTagName(GSXML.CLASSIFIER_ELEM); 
     137        for (int i = 0; i < classifiers.getLength(); i++) 
     138        { 
     139            Element cl = (Element) classifiers.item(i); 
     140            Element new_cl = (Element) this.doc.importNode(cl, false); // just import this node, not the children 
     141 
     142            // get the format info out, and put inside a classifier element 
     143            Element format_cl = (Element) new_cl.cloneNode(false); 
     144            Element format = (Element) GSXML.getChildByTagName(cl, GSXML.FORMAT_ELEM); 
     145            if (format != null) 
     146            { 
     147 
     148                //copy all the children 
     149                NodeList elems = format.getChildNodes(); 
     150                for (int j = 0; j < elems.getLength(); j++) 
     151                { 
     152                    format_cl.appendChild(this.doc.importNode(elems.item(j), true)); 
     153                } 
     154                cb_format_info.appendChild(format_cl); 
     155                format_found = true; 
     156            } 
     157 
     158        } 
     159 
     160        if (format_found) 
     161        { 
     162            this.format_info_map.put(CLASSIFIER_SERVICE, cb_format_info); 
     163        } 
     164 
     165        // look for document display format - is there a default doc type?? 
     166        String path = GSPath.appendLink(GSXML.DISPLAY_ELEM, GSXML.FORMAT_ELEM); 
     167        Element display_format = (Element) GSXML.getNodeByPath(extra_info, path); 
     168        if (display_format != null) 
     169        { 
     170            // check for docType option. 
     171            Element doc_type_opt = GSXML.getNamedElement(display_format, "gsf:option", GSXML.NAME_ATT, "documentType"); 
     172            if (doc_type_opt != null) 
     173            { 
     174                String value = doc_type_opt.getAttribute(GSXML.VALUE_ATT); 
     175                if (!value.equals("")) 
     176                { 
     177                    this.default_document_type = value; 
     178                } 
     179            } 
     180        } 
     181 
     182        return true; 
     183    } 
     184 
     185    protected Element getServiceDescription(String service_id, String lang, String subset) 
     186    { 
     187 
     188        if (service_id.equals(CLASSIFIER_SERVICE)) 
     189        { 
     190 
     191            Element class_list = (Element) GSXML.getChildByTagName(this.config_info, GSXML.CLASSIFIER_ELEM + GSXML.LIST_MODIFIER); 
     192            if (class_list == null) 
     193            { 
     194                // no classifiers specified 
     195                return null; 
     196            } 
     197 
     198            Element cb_service = this.doc.createElement(GSXML.SERVICE_ELEM); 
     199            cb_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BROWSE); 
     200            cb_service.setAttribute(GSXML.NAME_ATT, CLASSIFIER_SERVICE); 
     201            cb_service.appendChild(GSXML.createDisplayTextElement(this.doc, GSXML.DISPLAY_TEXT_NAME, getTextString(CLASSIFIER_SERVICE + ".name", lang))); 
     202            cb_service.appendChild(GSXML.createDisplayTextElement(this.doc, GSXML.DISPLAY_TEXT_DESCRIPTION, getTextString(CLASSIFIER_SERVICE + ".description", lang))); 
     203 
     204            Element cl_list = this.doc.createElement(GSXML.CLASSIFIER_ELEM + GSXML.LIST_MODIFIER); 
     205            cb_service.appendChild(cl_list); 
     206            NodeList classifiers = class_list.getElementsByTagName(GSXML.CLASSIFIER_ELEM); 
     207            for (int i = 0; i < classifiers.getLength(); i++) 
     208            { 
     209                Element cl = (Element) classifiers.item(i); 
     210                Element new_cl = (Element) this.doc.importNode(cl, false); // just import this node, not the children 
     211 
     212                //String content = cl.getAttribute(GSXML.CLASSIFIER_CONTENT_ATT); 
     213 
     214                //get the classify title  from the database 
     215                String class_id = cl.getAttribute(GSXML.NAME_ATT); 
     216                String content = getMetadata(class_id, "Title"); 
     217 
     218                cl_list.appendChild(new_cl); 
     219                String text = GSXML.getDisplayText(cl, GSXML.DISPLAY_TEXT_NAME, lang, "en"); 
     220                if (text == null || text.equals("")) 
     221                { 
     222                    // no display element was specified, use the metadata name 
     223                    // for now this looks in the class properties file 
     224                    // this needs to use a general metadata thing instead 
     225                    text = getMetadataNameText(content + ".buttonname", lang); 
     226                } 
     227                if (text == null) 
     228                { 
     229                    text = content; 
     230                } 
     231 
     232                Element cl_name = GSXML.createDisplayTextElement(this.doc, GSXML.DISPLAY_TEXT_NAME, text); 
     233                new_cl.appendChild(cl_name); 
     234 
     235                // description 
     236 
     237                String meta_name = getMetadataNameText(content, lang); 
     238                if (meta_name == null) 
     239                { 
     240                    meta_name = content; 
     241                } 
     242                String[] array = { meta_name }; 
     243                String description = getTextString("ClassifierBrowse.classifier_help", lang, array); 
     244                Element cl_desc = GSXML.createDisplayTextElement(this.doc, GSXML.DISPLAY_TEXT_DESCRIPTION, description); 
     245                new_cl.appendChild(cl_desc); 
     246 
     247            } 
     248            return cb_service; 
     249        } 
     250 
     251        // these ones are probably never called, but put them here just in case 
     252 
     253        if (service_id.equals(CLASSIFIER_METADATA_SERVICE)) 
     254        { 
     255 
     256            Element cbmr_service = this.doc.createElement(GSXML.SERVICE_ELEM); 
     257            cbmr_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE); 
     258            cbmr_service.setAttribute(GSXML.NAME_ATT, CLASSIFIER_METADATA_SERVICE); 
     259            return cbmr_service; 
     260        } 
     261 
    180262        return null; 
    181         } 
    182          
    183         Element cb_service = this.doc.createElement(GSXML.SERVICE_ELEM); 
    184         cb_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BROWSE); 
    185         cb_service.setAttribute(GSXML.NAME_ATT, CLASSIFIER_SERVICE); 
    186         cb_service.appendChild(GSXML.createDisplayTextElement(this.doc, GSXML.DISPLAY_TEXT_NAME,  getTextString(CLASSIFIER_SERVICE+".name", lang))); 
    187         cb_service.appendChild(GSXML.createDisplayTextElement(this.doc, GSXML.DISPLAY_TEXT_DESCRIPTION,  getTextString(CLASSIFIER_SERVICE+".description", lang))); 
    188          
    189         Element cl_list = this.doc.createElement(GSXML.CLASSIFIER_ELEM+GSXML.LIST_MODIFIER); 
    190         cb_service.appendChild(cl_list); 
    191         NodeList classifiers = class_list.getElementsByTagName(GSXML.CLASSIFIER_ELEM); 
    192         for(int i=0; i<classifiers.getLength(); i++) { 
    193         Element cl = (Element)classifiers.item(i); 
    194         Element new_cl = (Element)this.doc.importNode(cl, false); // just import this node, not the children 
    195              
    196             //String content = cl.getAttribute(GSXML.CLASSIFIER_CONTENT_ATT); 
    197          
    198         //get the classify title  from the database 
    199              String class_id =  cl.getAttribute(GSXML.NAME_ATT); 
    200          String content = getMetadata(class_id,"Title");  
    201  
    202                 cl_list.appendChild(new_cl); 
    203         String text = GSXML.getDisplayText(cl,  
    204                            GSXML.DISPLAY_TEXT_NAME,  
    205                            lang, "en"); 
    206         if (text == null || text.equals("")) { 
    207             // no display element was specified, use the metadata name 
    208             // for now this looks in the class properties file 
    209             // this needs to use a general metadata thing instead 
    210             text = getMetadataNameText(content+".buttonname", lang); 
    211         } 
    212         if (text == null) { 
    213             text = content; 
    214         } 
    215          
    216          
    217         Element cl_name = GSXML.createDisplayTextElement(this.doc, GSXML.DISPLAY_TEXT_NAME, text); 
    218         new_cl.appendChild(cl_name); 
    219  
    220         // description 
    221          
    222         String meta_name = getMetadataNameText(content, lang); 
    223         if (meta_name==null) { 
    224             meta_name = content; 
    225         } 
    226         String [] array = {meta_name}; 
    227         String description = getTextString("ClassifierBrowse.classifier_help", lang, array); 
    228         Element cl_desc = GSXML.createDisplayTextElement(this.doc, GSXML.DISPLAY_TEXT_DESCRIPTION, description); 
    229         new_cl.appendChild(cl_desc); 
    230          
    231         } 
    232         return cb_service; 
    233     } 
    234      
    235     // these ones are probably never called, but put them here just in case 
    236      
    237     if (service_id.equals(CLASSIFIER_METADATA_SERVICE)) { 
    238          
    239         Element cbmr_service = this.doc.createElement(GSXML.SERVICE_ELEM); 
    240         cbmr_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE); 
    241         cbmr_service.setAttribute(GSXML.NAME_ATT, CLASSIFIER_METADATA_SERVICE); 
    242         return cbmr_service; 
    243     } 
    244  
    245     return null; 
    246     } 
    247  
    248     /** this looks for any classifier specific display or format info from extra_info and adds it in to the correct place in info */ 
    249     static boolean extractExtraClassifierInfo(Element info, Element extra_info) { 
    250      
    251     if (extra_info == null) { 
    252         return false; 
    253     } 
    254      
    255     Document owner = info.getOwnerDocument(); 
    256     // so far we have display and format elements that we need for classifiers 
    257     NodeList classifiers = info.getElementsByTagName(GSXML.CLASSIFIER_ELEM); 
    258     Element config_browse = (Element)GSXML.getChildByTagName(extra_info, GSXML.BROWSE_ELEM); 
    259  
    260     for (int i=0; i<classifiers.getLength();i++) { 
    261         Element cl = (Element)classifiers.item(i); 
    262         String name = cl.getAttribute(GSXML.NAME_ATT); 
    263  
    264         //Element node_extra = GSXML.getNamedElement(config_browse, 
    265         //                         GSXML.CLASSIFIER_ELEM, 
    266         //                         GSXML.NAME_ATT, 
    267         //                         name); 
    268             //now use the position to get the node - CL1  
    269         // assumes the same number of classifiers in collectionCOnfig as in buildConfig 
    270         //            int position = Integer.parseInt(name.substring(2)); 
    271          
    272         Element node_extra = null; 
    273             NodeList cls = config_browse.getElementsByTagName(GSXML.CLASSIFIER_ELEM); 
    274             //if (position >0 && position <= cls.getLength()) { 
    275         //    node_extra  = (Element) cls.item((position -1));  
    276         //} 
    277         if (i<cls.getLength()) { 
    278           node_extra = (Element) cls.item(i); 
    279         } 
    280  
    281         if (node_extra == null) { 
    282         logger.error("GS2REtrieve: haven't found extra info for classifier named "+name); 
    283         continue; 
    284         } 
    285          
    286         // get the display elements if any - displayName 
    287         NodeList display_names = node_extra.getElementsByTagName(GSXML.DISPLAY_TEXT_ELEM); 
    288         if (display_names !=null) { 
    289         Element display = owner.createElement(GSXML.DISPLAY_ELEM); 
    290         for (int j=0; j<display_names.getLength(); j++) { 
    291             Element e = (Element)display_names.item(j); 
    292             cl.appendChild(owner.importNode(e, true)); 
    293              
    294         } 
    295         } 
    296          
    297         // get the format element if any  
    298         Element format = (Element)GSXML.getChildByTagName(node_extra, GSXML.FORMAT_ELEM); 
    299         if (format==null) { // try a generic one that applies to all classifiers 
    300         format = (Element)GSXML.getChildByTagName(extra_info, 
    301                               GSXML.FORMAT_ELEM); 
    302         } 
    303         if (format!=null) { // append to index info 
    304         cl.appendChild(owner.importNode(format, true)); 
    305         } 
    306     } // for each classifier 
    307  
    308     // now check for default format info 
    309     Element default_format = (Element)GSXML.getChildByTagName(config_browse, GSXML.FORMAT_ELEM); 
    310     if (default_format!=null) { // append to  info 
    311         info.appendChild(owner.importNode(default_format, true)); 
    312     } 
    313  
    314     return true; 
    315     } 
    316          
    317     protected Element processClassifierBrowse(Element request) { 
    318      
    319     // Create a new (empty) result message 
    320     Element result = this.doc.createElement(GSXML.RESPONSE_ELEM); 
    321     result.setAttribute(GSXML.FROM_ATT, CLASSIFIER_SERVICE); 
    322     result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS); 
    323      
    324     String lang = request.getAttribute(GSXML.LANG_ATT); 
    325     Element query_node_list = (Element) GSXML.getChildByTagName(request, GSXML.CLASS_NODE_ELEM+GSXML.LIST_MODIFIER); 
    326     if (query_node_list == null) { 
    327         logger.error(" ClassifierBrowse request specified no doc nodes.\n"); 
    328         return result; 
    329     } 
    330  
    331     // Get the parameters of the request 
    332     Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER); 
    333     if (param_list == null) { 
    334         logger.error(" ClassifierBrowse request had no paramList."); 
    335         return result;  // Return the empty result 
    336     } 
    337      
    338     // the type of info required 
    339     boolean want_structure = false; 
    340     boolean want_info = false; 
    341  
    342     ArrayList<String> info_types=new ArrayList<String>(); 
    343     // The document structure information desired 
    344     boolean want_ancestors = false; 
    345     boolean want_parent = false; 
    346     boolean want_siblings = false; 
    347     boolean want_children = false; 
    348     boolean want_descendants = false; 
    349  
    350     boolean want_entire_structure = false; 
    351     // Process the request parameters 
    352     NodeList params = param_list.getElementsByTagName(GSXML.PARAM_ELEM); 
    353     for (int i=0; i<params.getLength();i++) { 
    354          
    355         Element param = (Element)params.item(i); 
    356         String p_name = param.getAttribute(GSXML.NAME_ATT); 
    357         String p_value = GSXML.getValue(param); 
    358         // Identify the structure information desired 
    359         if (p_name.equals(STRUCT_PARAM)) { 
    360         want_structure = true; 
    361          
    362         // This is NOT locale sensitive 
    363         if (p_value.equals(STRUCT_ANCESTORS)) 
    364             want_ancestors = true; 
    365         else if (p_value.equals(STRUCT_PARENT)) 
    366             want_parent = true; 
    367         else if (p_value.equals(STRUCT_SIBS)) 
    368             want_siblings = true; 
    369         else if (p_value.equals(STRUCT_CHILDREN)) 
    370             want_children = true; 
    371         else if (p_value.equals(STRUCT_DESCENDS)) 
    372             want_descendants = true; 
    373         else if (p_value.equals(STRUCT_ENTIRE)) 
    374             want_entire_structure = true; 
     263    } 
     264 
     265    /** 
     266     * this looks for any classifier specific display or format info from 
     267     * extra_info and adds it in to the correct place in info 
     268     */ 
     269    static boolean extractExtraClassifierInfo(Element info, Element extra_info) 
     270    { 
     271 
     272        if (extra_info == null) 
     273        { 
     274            return false; 
     275        } 
     276 
     277        Document owner = info.getOwnerDocument(); 
     278        // so far we have display and format elements that we need for classifiers 
     279        NodeList classifiers = info.getElementsByTagName(GSXML.CLASSIFIER_ELEM); 
     280        Element config_browse = (Element) GSXML.getChildByTagName(extra_info, GSXML.BROWSE_ELEM); 
     281 
     282        for (int i = 0; i < classifiers.getLength(); i++) 
     283        { 
     284            Element cl = (Element) classifiers.item(i); 
     285            String name = cl.getAttribute(GSXML.NAME_ATT); 
     286 
     287            //Element node_extra = GSXML.getNamedElement(config_browse, 
     288            //                         GSXML.CLASSIFIER_ELEM, 
     289            //                         GSXML.NAME_ATT, 
     290            //                         name); 
     291            //now use the position to get the node - CL1  
     292            // assumes the same number of classifiers in collectionCOnfig as in buildConfig 
     293            //            int position = Integer.parseInt(name.substring(2)); 
     294 
     295            Element node_extra = null; 
     296            NodeList cls = config_browse.getElementsByTagName(GSXML.CLASSIFIER_ELEM); 
     297            //if (position >0 && position <= cls.getLength()) { 
     298            //    node_extra  = (Element) cls.item((position -1));  
     299            //} 
     300            if (i < cls.getLength()) 
     301            { 
     302                node_extra = (Element) cls.item(i); 
     303            } 
     304 
     305            if (node_extra == null) 
     306            { 
     307                logger.error("GS2REtrieve: haven't found extra info for classifier named " + name); 
     308                continue; 
     309            } 
     310 
     311            // get the display elements if any - displayName 
     312            NodeList display_names = node_extra.getElementsByTagName(GSXML.DISPLAY_TEXT_ELEM); 
     313            if (display_names != null) 
     314            { 
     315                Element display = owner.createElement(GSXML.DISPLAY_ELEM); 
     316                for (int j = 0; j < display_names.getLength(); j++) 
     317                { 
     318                    Element e = (Element) display_names.item(j); 
     319                    cl.appendChild(owner.importNode(e, true)); 
     320 
     321                } 
     322            } 
     323 
     324            // get the format element if any  
     325            Element format = (Element) GSXML.getChildByTagName(node_extra, GSXML.FORMAT_ELEM); 
     326            if (format == null) 
     327            { // try a generic one that applies to all classifiers 
     328                format = (Element) GSXML.getChildByTagName(extra_info, GSXML.FORMAT_ELEM); 
     329            } 
     330            if (format != null) 
     331            { // append to index info 
     332                cl.appendChild(owner.importNode(format, true)); 
     333            } 
     334        } // for each classifier 
     335 
     336        // now check for default format info 
     337        Element default_format = (Element) GSXML.getChildByTagName(config_browse, GSXML.FORMAT_ELEM); 
     338        if (default_format != null) 
     339        { // append to  info 
     340            info.appendChild(owner.importNode(default_format, true)); 
     341        } 
     342 
     343        return true; 
     344    } 
     345 
     346    protected Element processClassifierBrowse(Element request) 
     347    { 
     348 
     349        // Create a new (empty) result message 
     350        Element result = this.doc.createElement(GSXML.RESPONSE_ELEM); 
     351        result.setAttribute(GSXML.FROM_ATT, CLASSIFIER_SERVICE); 
     352        result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS); 
     353 
     354        String lang = request.getAttribute(GSXML.LANG_ATT); 
     355        Element query_node_list = (Element) GSXML.getChildByTagName(request, GSXML.CLASS_NODE_ELEM + GSXML.LIST_MODIFIER); 
     356        if (query_node_list == null) 
     357        { 
     358            logger.error(" ClassifierBrowse request specified no doc nodes.\n"); 
     359            return result; 
     360        } 
     361 
     362        // Get the parameters of the request 
     363        Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER); 
     364        if (param_list == null) 
     365        { 
     366            logger.error(" ClassifierBrowse request had no paramList."); 
     367            return result; // Return the empty result 
     368        } 
     369 
     370        // the type of info required 
     371        boolean want_structure = false; 
     372        boolean want_info = false; 
     373 
     374        ArrayList<String> info_types = new ArrayList<String>(); 
     375        // The document structure information desired 
     376        boolean want_ancestors = false; 
     377        boolean want_parent = false; 
     378        boolean want_siblings = false; 
     379        boolean want_children = false; 
     380        boolean want_descendants = false; 
     381 
     382        boolean want_entire_structure = false; 
     383        // Process the request parameters 
     384        NodeList params = param_list.getElementsByTagName(GSXML.PARAM_ELEM); 
     385        for (int i = 0; i < params.getLength(); i++) 
     386        { 
     387 
     388            Element param = (Element) params.item(i); 
     389            String p_name = param.getAttribute(GSXML.NAME_ATT); 
     390            String p_value = GSXML.getValue(param); 
     391            // Identify the structure information desired 
     392            if (p_name.equals(STRUCT_PARAM)) 
     393            { 
     394                want_structure = true; 
     395 
     396                // This is NOT locale sensitive 
     397                if (p_value.equals(STRUCT_ANCESTORS)) 
     398                    want_ancestors = true; 
     399                else if (p_value.equals(STRUCT_PARENT)) 
     400                    want_parent = true; 
     401                else if (p_value.equals(STRUCT_SIBS)) 
     402                    want_siblings = true; 
     403                else if (p_value.equals(STRUCT_CHILDREN)) 
     404                    want_children = true; 
     405                else if (p_value.equals(STRUCT_DESCENDS)) 
     406                    want_descendants = true; 
     407                else if (p_value.equals(STRUCT_ENTIRE)) 
     408                    want_entire_structure = true; 
     409                else 
     410                    logger.error("AbstractDocumentRetrieve Warning: Unknown value \"" + p_value + "\"."); 
     411            } 
     412            else if (p_name.equals(INFO_PARAM)) 
     413            { 
     414                want_info = true; 
     415                info_types.add(p_value); 
     416            } 
     417        } 
     418 
     419        // Make sure there is no repeated information 
     420        if (want_ancestors) 
     421            want_parent = false; 
     422        if (want_descendants) 
     423            want_children = false; 
     424 
     425        // the node list to hold the results 
     426        Element node_list = this.doc.createElement(GSXML.CLASS_NODE_ELEM + GSXML.LIST_MODIFIER); 
     427        result.appendChild(node_list); 
     428 
     429        // Get the nodes 
     430        String[] node_ids = GSXML.getAttributeValuesFromList(query_node_list, GSXML.NODE_ID_ATT); 
     431        for (int i = 0; i < node_ids.length; i++) 
     432        { 
     433            // Add the document to the list 
     434            Element node = this.doc.createElement(GSXML.CLASS_NODE_ELEM); 
     435            node_list.appendChild(node); 
     436 
     437            String node_id = node_ids[i]; 
     438            node.setAttribute(GSXML.NODE_ID_ATT, node_id); 
     439 
     440            if (idNeedsTranslating(node_id)) 
     441            { 
     442                node_id = translateId(node_id); 
     443                if (node_id == null) 
     444                { 
     445                    continue; 
     446                } 
     447                node.setAttribute(GSXML.NODE_ID_ATT, node_id); 
     448            } 
     449 
     450            if (want_info) 
     451            { 
     452 
     453                Element node_info_elem = this.doc.createElement("nodeStructureInfo"); 
     454                node.appendChild(node_info_elem); 
     455 
     456                for (int j = 0; j < info_types.size(); j++) 
     457                { 
     458                    String info_type = info_types.get(j); 
     459                    String info_value = getStructureInfo(node_id, info_type); 
     460                    if (info_value != null) 
     461                    { 
     462                        Element info_elem = this.doc.createElement("info"); 
     463                        info_elem.setAttribute(GSXML.NAME_ATT, info_type); 
     464                        info_elem.setAttribute(GSXML.VALUE_ATT, info_value); 
     465                        node_info_elem.appendChild(info_elem); 
     466                    } 
     467                } 
     468            } 
     469 
     470            if (want_structure) 
     471            { 
     472                // all structure info goes into a nodeStructure elem 
     473                Element structure_elem = this.doc.createElement(GSXML.NODE_STRUCTURE_ELEM); 
     474                node.appendChild(structure_elem); 
     475 
     476                if (want_entire_structure) 
     477                { 
     478                    String root_id = getRootId(node_id); 
     479                    Element root_node = createClassifierNode(root_id); //, true, false); 
     480                    addDescendants(root_node, root_id, true); 
     481                    structure_elem.appendChild(root_node); 
     482                    continue; // with the next document, we dont need to do any more here 
     483                } 
     484 
     485                // Add the requested structure information 
     486                Element base_node = createClassifierNode(node_id); //, false, false); 
     487 
     488                //Ancestors: continually add parent nodes until the root is reached 
     489                Element top_node = base_node; // the top node so far 
     490                if (want_ancestors) 
     491                { 
     492                    String current_id = node_id; 
     493                    while (true) 
     494                    { 
     495                        String parent_id = getParentId(current_id); 
     496                        //Element parent = getParent(current_id); 
     497                        if (parent_id == null) 
     498                            break; // no parent 
     499                        Element parent_node = createClassifierNode(parent_id); 
     500                        parent_node.appendChild(top_node); 
     501                        current_id = parent_id;//.getAttribute(GSXML.NODE_ID_ATT); 
     502                        top_node = parent_node; 
     503                    } 
     504                } 
     505                // Parent: get the parent of the selected node 
     506                else if (want_parent) 
     507                { 
     508                    String parent_id = getParentId(node_id); 
     509                    if (parent_id != null) 
     510                    { 
     511                        Element parent_node = createClassifierNode(parent_id); 
     512                        parent_node.appendChild(base_node); 
     513                        top_node = parent_node; 
     514                    } 
     515                } 
     516 
     517                // now the top node is the root of the structure 
     518                structure_elem.appendChild(top_node); 
     519 
     520                //Siblings: get the other descendants of the selected node's parent 
     521                if (want_siblings) 
     522                { 
     523 
     524                    Element parent_node = (Element) base_node.getParentNode(); // this may be the structure element if there has been no request for parents or ancestors 
     525                    String parent_id = getParentId(node_id); 
     526                    // add siblings, - returns a pointer to the new current node  
     527                    base_node = addSiblings(parent_node, parent_id, node_id); 
     528                } 
     529 
     530                // Children: get the descendants, but only one level deep 
     531                if (want_children) 
     532                { 
     533                    addDescendants(base_node, node_id, false); 
     534                } 
     535                // Descendants: recursively get every descendant  
     536                else if (want_descendants) 
     537                { 
     538                    addDescendants(base_node, node_id, true); 
     539                } 
     540            } // if want structure 
     541        } // for each doc 
     542        return result; 
     543    } 
     544 
     545    protected Element processClassifierBrowseMetadataRetrieve(Element request) 
     546    { 
     547 
     548        // Create a new (empty) result message 
     549        Element result = this.doc.createElement(GSXML.RESPONSE_ELEM); 
     550 
     551        String lang = request.getAttribute(GSXML.LANG_ATT); 
     552        result.setAttribute(GSXML.FROM_ATT, CLASSIFIER_METADATA_SERVICE); 
     553        result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS); 
     554 
     555        // Get the parameters of the request 
     556        Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER); 
     557        if (param_list == null) 
     558        { 
     559            logger.error("AbstractBrowse, ClassifierBrowseMetadataRetrieve Error: missing paramList.\n"); 
     560            return result; // Return the empty result 
     561        } 
     562 
     563        // The metadata information required 
     564        ArrayList<String> metadata_names_list = new ArrayList<String>(); 
     565        boolean all_metadata = false; 
     566        // Process the request parameters 
     567        Element param = GSXML.getFirstElementChild(param_list);//(Element) param_list.getFirstChild(); 
     568        while (param != null) 
     569        { 
     570            // Identify the metadata information desired 
     571            if (param.getAttribute(GSXML.NAME_ATT).equals("metadata")) 
     572            { 
     573                String metadata = GSXML.getValue(param); 
     574                if (metadata.equals("all")) 
     575                { 
     576                    all_metadata = true; 
     577                    break; 
     578                } 
     579                metadata_names_list.add(metadata); 
     580            } 
     581            param = (Element) param.getNextSibling(); 
     582        } 
     583 
     584        Element node_list = this.doc.createElement(GSXML.CLASS_NODE_ELEM + GSXML.LIST_MODIFIER); 
     585        result.appendChild(node_list); 
     586 
     587        // Get the nodes 
     588        Element request_node_list = (Element) GSXML.getChildByTagName(request, GSXML.CLASS_NODE_ELEM + GSXML.LIST_MODIFIER); 
     589        if (request_node_list == null) 
     590        { 
     591            logger.error(" ClassifierBrowseMetadataRetrieve request had no " + GSXML.CLASS_NODE_ELEM + GSXML.LIST_MODIFIER); 
     592            return result; 
     593        } 
     594 
     595        NodeList request_nodes = request_node_list.getChildNodes(); 
     596        for (int i = 0; i < request_nodes.getLength(); i++) 
     597        { 
     598            Element request_node = (Element) request_nodes.item(i); 
     599            String node_id = request_node.getAttribute(GSXML.NODE_ID_ATT); 
     600 
     601            // Add the document to the results list 
     602            Element new_node = (Element) this.doc.importNode(request_node, false); 
     603            node_list.appendChild(new_node); 
     604 
     605            if (idNeedsTranslating(node_id)) 
     606            { 
     607                node_id = translateId(node_id); 
     608            } 
     609            if (node_id == null) 
     610            { 
     611                continue; 
     612            } 
     613 
     614            Element metadata_list = getMetadataList(node_id, all_metadata, metadata_names_list); 
     615            new_node.appendChild(metadata_list); 
     616        } 
     617 
     618        return result; 
     619    } 
     620 
     621    /** Creates a classifier node */ 
     622    protected Element createClassifierNode(String node_id) 
     623    { 
     624        Element node = this.doc.createElement(GSXML.CLASS_NODE_ELEM); 
     625        node.setAttribute(GSXML.NODE_ID_ATT, node_id); 
     626        return node; 
     627    } 
     628 
     629    /** 
     630     * create an element to go into the structure. A node element has the form 
     631     * <docNode nodeId='xxx' nodeType='leaf' docType='hierarchy'/> 
     632     */ 
     633    protected Element createDocNode(String node_id) 
     634    { 
     635        Element node = this.doc.createElement(GSXML.DOC_NODE_ELEM); 
     636        node.setAttribute(GSXML.NODE_ID_ATT, node_id); 
     637 
     638        String doc_type = null; 
     639        if (default_document_type != null) 
     640        { 
     641            doc_type = default_document_type; 
     642        } 
    375643        else 
    376             logger.error("AbstractDocumentRetrieve Warning: Unknown value \"" + p_value + "\"."); 
    377         } else if (p_name.equals(INFO_PARAM)) { 
    378         want_info = true; 
    379         info_types.add(p_value); 
    380         } 
    381     } 
    382  
    383     // Make sure there is no repeated information 
    384     if (want_ancestors) 
    385         want_parent = false; 
    386     if (want_descendants) 
    387         want_children = false; 
    388      
    389     // the node list to hold the results 
    390     Element node_list = this.doc.createElement(GSXML.CLASS_NODE_ELEM+GSXML.LIST_MODIFIER); 
    391     result.appendChild(node_list); 
    392      
    393     // Get the nodes 
    394     String[] node_ids = GSXML.getAttributeValuesFromList(query_node_list,  
    395                                  GSXML.NODE_ID_ATT); 
    396     for (int i = 0; i < node_ids.length; i++) { 
    397         // Add the document to the list 
    398         Element node = this.doc.createElement(GSXML.CLASS_NODE_ELEM); 
    399         node_list.appendChild(node); 
    400  
    401         String node_id = node_ids[i]; 
    402         node.setAttribute(GSXML.NODE_ID_ATT, node_id); 
    403          
    404         if (idNeedsTranslating(node_id)) { 
    405         node_id = translateId(node_id); 
    406         if (node_id == null) { 
    407             continue; 
    408         } 
    409         node.setAttribute(GSXML.NODE_ID_ATT, node_id); 
    410         } 
    411          
    412         if (want_info) { 
    413  
    414         Element node_info_elem = this.doc.createElement("nodeStructureInfo"); 
    415         node.appendChild(node_info_elem); 
    416          
    417         for (int j=0; j<info_types.size(); j++) { 
    418             String info_type = info_types.get(j); 
    419             String info_value = getStructureInfo(node_id, info_type); 
    420             if (info_value != null) { 
    421             Element info_elem = this.doc.createElement("info"); 
    422             info_elem.setAttribute(GSXML.NAME_ATT, info_type); 
    423             info_elem.setAttribute(GSXML.VALUE_ATT, info_value); 
    424             node_info_elem.appendChild(info_elem); 
    425             } 
    426         } 
    427         } 
    428          
    429         if (want_structure) { 
    430         // all structure info goes into a nodeStructure elem 
    431         Element structure_elem = this.doc.createElement(GSXML.NODE_STRUCTURE_ELEM); 
    432         node.appendChild(structure_elem); 
    433          
    434         if (want_entire_structure) { 
    435             String root_id = getRootId(node_id); 
    436             Element root_node = createClassifierNode(root_id); //, true, false); 
    437             addDescendants(root_node, root_id, true); 
    438             structure_elem.appendChild(root_node); 
    439             continue; // with the next document, we dont need to do any more here 
    440         } 
    441          
    442         // Add the requested structure information 
    443         Element base_node = createClassifierNode(node_id); //, false, false); 
    444          
    445         //Ancestors: continually add parent nodes until the root is reached 
    446         Element top_node = base_node; // the top node so far 
    447         if (want_ancestors) { 
    448             String current_id = node_id; 
    449             while (true) { 
    450             String parent_id = getParentId(current_id); 
    451             //Element parent = getParent(current_id); 
    452             if (parent_id == null) 
    453                 break; // no parent 
    454             Element parent_node = createClassifierNode(parent_id); 
    455             parent_node.appendChild(top_node); 
    456             current_id = parent_id;//.getAttribute(GSXML.NODE_ID_ATT); 
    457             top_node = parent_node; 
    458             } 
    459         } 
    460         // Parent: get the parent of the selected node 
    461         else if (want_parent) { 
    462             String parent_id = getParentId(node_id); 
    463             if (parent_id != null) { 
    464             Element parent_node = createClassifierNode(parent_id); 
    465             parent_node.appendChild(base_node); 
    466             top_node = parent_node; 
    467             } 
    468         } 
    469          
    470         // now the top node is the root of the structure 
    471         structure_elem.appendChild(top_node); 
    472          
    473         //Siblings: get the other descendants of the selected node's parent 
    474         if (want_siblings) { 
    475              
    476             Element parent_node = (Element)base_node.getParentNode(); // this may be the structure element if there has been no request for parents or ancestors 
    477             String parent_id = getParentId(node_id); 
    478             // add siblings, - returns a pointer to the new current node  
    479             base_node = addSiblings(parent_node, parent_id, node_id); 
    480         } 
    481          
    482         // Children: get the descendants, but only one level deep 
    483         if (want_children) { 
    484             addDescendants(base_node, node_id, false); 
    485         }  
    486         // Descendants: recursively get every descendant  
    487         else if (want_descendants) { 
    488             addDescendants(base_node, node_id, true); 
    489         } 
    490         } // if want structure 
    491     } // for each doc 
    492     return result; 
    493     } 
    494  
    495  
    496     protected Element processClassifierBrowseMetadataRetrieve(Element request) { 
    497  
    498     // Create a new (empty) result message 
    499     Element result = this.doc.createElement(GSXML.RESPONSE_ELEM); 
    500  
    501     String lang = request.getAttribute(GSXML.LANG_ATT); 
    502     result.setAttribute(GSXML.FROM_ATT, CLASSIFIER_METADATA_SERVICE); 
    503     result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS); 
    504  
    505     // Get the parameters of the request 
    506     Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER); 
    507     if (param_list == null) { 
    508         logger.error("AbstractBrowse, ClassifierBrowseMetadataRetrieve Error: missing paramList.\n"); 
    509         return result;  // Return the empty result 
    510     } 
    511  
    512     // The metadata information required 
    513     ArrayList<String> metadata_names_list = new ArrayList<String>(); 
    514     boolean all_metadata = false; 
    515     // Process the request parameters 
    516     Element param = GSXML.getFirstElementChild(param_list);//(Element) param_list.getFirstChild(); 
    517     while (param != null) { 
    518         // Identify the metadata information desired 
    519         if (param.getAttribute(GSXML.NAME_ATT).equals("metadata")) { 
    520         String metadata = GSXML.getValue(param); 
    521         if (metadata.equals("all")) { 
    522             all_metadata = true; 
    523             break; 
    524         } 
    525         metadata_names_list.add(metadata); 
    526         }  
    527         param = (Element) param.getNextSibling(); 
    528     } 
    529      
    530     Element node_list = this.doc.createElement(GSXML.CLASS_NODE_ELEM+GSXML.LIST_MODIFIER); 
    531     result.appendChild(node_list); 
    532      
    533     // Get the nodes 
    534     Element request_node_list = (Element) GSXML.getChildByTagName(request, GSXML.CLASS_NODE_ELEM+GSXML.LIST_MODIFIER); 
    535     if (request_node_list == null) { 
    536         logger.error(" ClassifierBrowseMetadataRetrieve request had no "+GSXML.CLASS_NODE_ELEM+GSXML.LIST_MODIFIER); 
    537         return result; 
    538     } 
    539      
    540     NodeList request_nodes = request_node_list.getChildNodes(); 
    541     for (int i = 0; i < request_nodes.getLength(); i++) { 
    542         Element request_node = (Element) request_nodes.item(i); 
    543         String node_id = request_node.getAttribute(GSXML.NODE_ID_ATT); 
    544          
    545         // Add the document to the results list 
    546         Element new_node = (Element)this.doc.importNode(request_node, false); 
    547         node_list.appendChild(new_node); 
    548  
    549         if (idNeedsTranslating(node_id)) { 
    550         node_id = translateId(node_id); 
    551         } 
    552         if (node_id == null) { 
    553         continue; 
    554         } 
    555          
    556         Element metadata_list = getMetadataList(node_id, all_metadata, metadata_names_list); 
    557         new_node.appendChild(metadata_list); 
    558     } 
    559      
    560     return result; 
    561     } 
    562  
    563  
    564     /** Creates a classifier node */ 
    565     protected Element createClassifierNode(String node_id) 
    566     { 
    567     Element node = this.doc.createElement(GSXML.CLASS_NODE_ELEM); 
    568     node.setAttribute(GSXML.NODE_ID_ATT, node_id); 
    569     return node; 
    570     } 
    571  
    572     /** create an element to go into the structure. A node element 
    573      * has the form 
    574      * <docNode nodeId='xxx' nodeType='leaf' docType='hierarchy'/> 
    575      */ 
    576     protected Element createDocNode(String node_id) { 
    577     Element node = this.doc.createElement(GSXML.DOC_NODE_ELEM); 
    578     node.setAttribute(GSXML.NODE_ID_ATT, node_id); 
    579  
    580     String doc_type = null; 
    581     if (default_document_type != null) { 
    582         doc_type = default_document_type; 
    583     } else { 
    584         doc_type = getDocType(node_id); 
    585     } 
    586     node.setAttribute(GSXML.DOC_TYPE_ATT, doc_type); 
    587     String node_type = getNodeType(node_id, doc_type);   
    588     node.setAttribute(GSXML.NODE_TYPE_ATT, node_type); 
    589     return node; 
    590     } 
    591  
    592    /** returns the node type of the specified node. 
    593     should be one of  
    594     GSXML.NODE_TYPE_LEAF,  
    595     GSXML.NODE_TYPE_INTERNAL,  
    596     GSXML.NODE_TYPE_ROOT 
    597     */ 
    598     protected String getNodeType(String node_id, String doc_type) { 
    599     if (doc_type.equals(GSXML.DOC_TYPE_SIMPLE)) { 
    600         return GSXML.NODE_TYPE_LEAF; 
    601     } 
    602  
    603     if (getParentId(node_id)==null) { 
    604         return GSXML.NODE_TYPE_ROOT; 
    605     } 
    606     if (doc_type.equals(GSXML.DOC_TYPE_PAGED)) { 
    607          return GSXML.NODE_TYPE_LEAF; 
    608     } 
    609     if (getChildrenIds(node_id)==null) { 
    610         return GSXML.NODE_TYPE_LEAF; 
    611     } 
    612     return GSXML.NODE_TYPE_INTERNAL;     
    613      
    614     } 
    615  
    616     /** adds all the children of doc_id the the doc element, 
    617      * and if recursive=true, adds all their children as well*/ 
    618     protected void addDescendants(Element node, String node_id,  
    619                   boolean recursive) 
    620     { 
    621     ArrayList<String> child_ids = getChildrenIds(node_id); 
    622     if (child_ids==null) return; 
    623     for (int i=0; i< child_ids.size(); i++) { 
    624         String child_id = child_ids.get(i); 
    625         Element child_elem; 
    626         if (isDocumentId(child_id)) { 
    627         child_elem = createDocNode(child_id); 
    628         } else { 
    629         child_elem = createClassifierNode(child_id); 
    630         } 
    631         node.appendChild(child_elem); 
    632         if (recursive) { 
    633         addDescendants(child_elem, child_id, recursive); 
    634         } 
    635     } 
    636     } 
    637  
    638     /** adds all the siblings of current_id to the parent element.  
    639       returns the new current element*/ 
    640     protected Element addSiblings(Element parent_node, String parent_id,  
    641                   String current_id) { 
    642     Element current_node = GSXML.getFirstElementChild(parent_node);//(Element)parent_node.getFirstChild(); 
    643     if (current_node == null) { 
    644         // create a sensible error message 
    645         logger.error(" there should be a first child."); 
    646         return null; 
    647     } 
    648     // remove the current child,- will add it in later in its correct place 
    649     parent_node.removeChild(current_node); 
    650  
    651     // add in all the siblings, 
    652     addDescendants(parent_node, parent_id, false); 
    653  
    654     // find the node that is now the current node 
    655     // this assumes that the new node that was created is the same as  
    656     // the old one that was removed - we may want to replace the new one  
    657     // with the old one. 
    658     Element new_current = GSXML.getNamedElement(parent_node, current_node.getNodeName(), GSXML.NODE_ID_ATT, current_id); 
    659     return new_current; 
    660     } 
    661  
    662     /** returns true if oid ends in 
    663     .fc (firstchild),  
    664     .lc (lastchild),  
    665     .pr (parent),  
    666     .ns (next sibling),  
    667     .ps (prev sibling),  
    668     .rt (root)  
    669     .ss (specified sibling),  
    670     false otherwise  
    671     */ 
    672     protected boolean idNeedsTranslating(String node_id) { 
    673     return OID.needsTranslating(node_id); 
    674     } 
    675  
    676     /** returns the list of sibling ids, including the specified node_id */ 
    677     protected ArrayList<String> getSiblingIds(String node_id) { 
    678     String parent_id = getParentId(node_id); 
    679     if (parent_id == null) { 
    680         return null; 
    681     } 
    682     return getChildrenIds(parent_id); 
    683  
    684     } 
    685  
    686     /** if id ends in .fc, .pc etc, then translate it to the correct id */ 
    687     abstract protected String translateId(String node_id); 
    688  
    689     /** returns the document type of the doc that the specified node  
    690     belongs to. should be one of  
    691     GSXML.DOC_TYPE_SIMPLE,  
    692     GSXML.DOC_TYPE_PAGED,  
    693     GSXML.DOC_TYPE_HIERARCHY 
    694     */ 
    695     abstract protected String getDocType(String node_id); 
    696  
    697     /** returns the id of the root node of the document containing node node_id. . may be the same as node_id */ 
    698     abstract protected String getRootId(String node_id); 
    699     /** returns a list of the child ids in order, null if no children */ 
    700     abstract protected ArrayList<String> getChildrenIds(String node_id); 
    701     /** returns the node id of the parent node, null if no parent */ 
    702     abstract protected String getParentId(String node_id); 
    703   
    704     /** returns true if the id refers to a document (rather than  
    705      * a classifier node) 
    706      */ 
    707     abstract protected boolean isDocumentId(String node_id); 
    708  
    709     /** get the metadata for the classifier node node_id 
    710      * returns a metadataList element: 
    711      * <metadataList><metadata name="xxx">value</metadata></metadataList> 
    712      * if all_metadata is true, returns all available metadata, otherwise just 
    713      * returns requested metadata 
    714      */ 
    715     abstract protected Element getMetadataList(String node_id, 
    716                            boolean all_metadata, 
    717                            ArrayList<String> metadata_names); 
    718  
    719     /** get the particular metadata (identified by the metadata name) for the classifier node node_id 
    720      *  
    721      */ 
    722     abstract protected String getMetadata(String node_id, String metadata_name); 
    723  
    724  
    725     /** returns the structural information asked for. 
    726      * info_type may be one of 
    727      * INFO_NUM_SIBS, INFO_NUM_CHILDREN, INFO_SIB_POS 
    728      */ 
    729     abstract protected String getStructureInfo(String node_id, String info_type);     
    730     
    731 }    
     644        { 
     645            doc_type = getDocType(node_id); 
     646        } 
     647        node.setAttribute(GSXML.DOC_TYPE_ATT, doc_type); 
     648        String node_type = getNodeType(node_id, doc_type); 
     649        node.setAttribute(GSXML.NODE_TYPE_ATT, node_type); 
     650        return node; 
     651    } 
     652 
     653    /** 
     654     * returns the node type of the specified node. should be one of 
     655     * GSXML.NODE_TYPE_LEAF, GSXML.NODE_TYPE_INTERNAL, GSXML.NODE_TYPE_ROOT 
     656     */ 
     657    protected String getNodeType(String node_id, String doc_type) 
     658    { 
     659        if (doc_type.equals(GSXML.DOC_TYPE_SIMPLE)) 
     660        { 
     661            return GSXML.NODE_TYPE_LEAF; 
     662        } 
     663 
     664        if (getParentId(node_id) == null) 
     665        { 
     666            return GSXML.NODE_TYPE_ROOT; 
     667        } 
     668        if (doc_type.equals(GSXML.DOC_TYPE_PAGED)) 
     669        { 
     670            return GSXML.NODE_TYPE_LEAF; 
     671        } 
     672        if (getChildrenIds(node_id) == null) 
     673        { 
     674            return GSXML.NODE_TYPE_LEAF; 
     675        } 
     676        return GSXML.NODE_TYPE_INTERNAL; 
     677 
     678    } 
     679 
     680    /** 
     681     * adds all the children of doc_id the the doc element, and if 
     682     * recursive=true, adds all their children as well 
     683     */ 
     684    protected void addDescendants(Element node, String node_id, boolean recursive) 
     685    { 
     686        ArrayList<String> child_ids = getChildrenIds(node_id); 
     687        if (child_ids == null) 
     688            return; 
     689        for (int i = 0; i < child_ids.size(); i++) 
     690        { 
     691            String child_id = child_ids.get(i); 
     692            Element child_elem; 
     693            if (isDocumentId(child_id)) 
     694            { 
     695                child_elem = createDocNode(child_id); 
     696            } 
     697            else 
     698            { 
     699                child_elem = createClassifierNode(child_id); 
     700            } 
     701            node.appendChild(child_elem); 
     702            if (recursive) 
     703            { 
     704                addDescendants(child_elem, child_id, recursive); 
     705            } 
     706        } 
     707    } 
     708 
     709    /** 
     710     * adds all the siblings of current_id to the parent element. returns the 
     711     * new current element 
     712     */ 
     713    protected Element addSiblings(Element parent_node, String parent_id, String current_id) 
     714    { 
     715        Element current_node = GSXML.getFirstElementChild(parent_node);//(Element)parent_node.getFirstChild(); 
     716        if (current_node == null) 
     717        { 
     718            // create a sensible error message 
     719            logger.error(" there should be a first child."); 
     720            return null; 
     721        } 
     722        // remove the current child,- will add it in later in its correct place 
     723        parent_node.removeChild(current_node); 
     724 
     725        // add in all the siblings, 
     726        addDescendants(parent_node, parent_id, false); 
     727 
     728        // find the node that is now the current node 
     729        // this assumes that the new node that was created is the same as  
     730        // the old one that was removed - we may want to replace the new one  
     731        // with the old one. 
     732        Element new_current = GSXML.getNamedElement(parent_node, current_node.getNodeName(), GSXML.NODE_ID_ATT, current_id); 
     733        return new_current; 
     734    } 
     735 
     736    /** 
     737     * returns true if oid ends in .fc (firstchild), .lc (lastchild), .pr 
     738     * (parent), .ns (next sibling), .ps (prev sibling), .rt (root) .ss 
     739     * (specified sibling), false otherwise 
     740     */ 
     741    protected boolean idNeedsTranslating(String node_id) 
     742    { 
     743        return OID.needsTranslating(node_id); 
     744    } 
     745 
     746    /** returns the list of sibling ids, including the specified node_id */ 
     747    protected ArrayList<String> getSiblingIds(String node_id) 
     748    { 
     749        String parent_id = getParentId(node_id); 
     750        if (parent_id == null) 
     751        { 
     752            return null; 
     753        } 
     754        return getChildrenIds(parent_id); 
     755 
     756    } 
     757 
     758    /** if id ends in .fc, .pc etc, then translate it to the correct id */ 
     759    abstract protected String translateId(String node_id); 
     760 
     761    /** 
     762     * returns the document type of the doc that the specified node belongs to. 
     763     * should be one of GSXML.DOC_TYPE_SIMPLE, GSXML.DOC_TYPE_PAGED, 
     764     * GSXML.DOC_TYPE_HIERARCHY 
     765     */ 
     766    abstract protected String getDocType(String node_id); 
     767 
     768    /** 
     769     * returns the id of the root node of the document containing node node_id. 
     770     * . may be the same as node_id 
     771     */ 
     772    abstract protected String getRootId(String node_id); 
     773 
     774    /** returns a list of the child ids in order, null if no children */ 
     775    abstract protected ArrayList<String> getChildrenIds(String node_id); 
     776 
     777    /** returns the node id of the parent node, null if no parent */ 
     778    abstract protected String getParentId(String node_id); 
     779 
     780    /** 
     781     * returns true if the id refers to a document (rather than a classifier 
     782     * node) 
     783     */ 
     784    abstract protected boolean isDocumentId(String node_id); 
     785 
     786    /** 
     787     * get the metadata for the classifier node node_id returns a metadataList 
     788     * element: <metadataList><metadata 
     789     * name="xxx">value</metadata></metadataList> if all_metadata is true, 
     790     * returns all available metadata, otherwise just returns requested metadata 
     791     */ 
     792    abstract protected Element getMetadataList(String node_id, boolean all_metadata, ArrayList<String> metadata_names); 
     793 
     794    /** 
     795     * get the particular metadata (identified by the metadata name) for the 
     796     * classifier node node_id 
     797     *  
     798     */ 
     799    abstract protected String getMetadata(String node_id, String metadata_name); 
     800 
     801    /** 
     802     * returns the structural information asked for. info_type may be one of 
     803     * INFO_NUM_SIBS, INFO_NUM_CHILDREN, INFO_SIB_POS 
     804     */ 
     805    abstract protected String getStructureInfo(String node_id, String info_type); 
     806 
     807}