Changeset 24980


Ignore:
Timestamp:
2012-01-26T10:44:51+13:00 (12 years ago)
Author:
sjm84
Message:

Reformatting this file ahead of some changes

File:
1 edited

Legend:

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

    r24393 r24980  
    3232// XML classes
    3333import org.w3c.dom.Document;
    34 import org.w3c.dom.Element; 
     34import org.w3c.dom.Element;
    3535import org.w3c.dom.NodeList;
    3636
     
    4242import java.util.ArrayList;
    4343
    44 
    4544import org.apache.log4j.*;
    4645
    47 /** Abstract class for Document Retrieval Services
    48  *
     46/**
     47 * Abstract class for Document Retrieval Services
     48 *
    4949 * @author <a href="mailto:[email protected]">Katherine Don</a>
    5050 */
    5151
    52 public abstract class AbstractDocumentRetrieve
    53     extends ServiceRack {
    54 
    55     static Logger logger = Logger.getLogger(org.greenstone.gsdl3.service.AbstractDocumentRetrieve.class.getName());
    56 
    57     // the services on offer
    58     protected static final String DOCUMENT_STRUCTURE_RETRIEVE_SERVICE = "DocumentStructureRetrieve";
    59     protected static final String DOCUMENT_METADATA_RETRIEVE_SERVICE = "DocumentMetadataRetrieve";
    60     protected static final String DOCUMENT_CONTENT_RETRIEVE_SERVICE = "DocumentContentRetrieve";
    61    
    62     protected static final String STRUCT_PARAM = "structure";
    63     protected static final String INFO_PARAM = "info";
    64    
    65     protected static final String STRUCT_ANCESTORS = "ancestors";
    66     protected static final String STRUCT_PARENT = "parent";
    67     protected static final String STRUCT_SIBS = "siblings";
    68     protected static final String STRUCT_CHILDREN = "children";
    69     protected static final String STRUCT_DESCENDS = "descendants";
    70     protected static final String STRUCT_ENTIRE = "entire";
    71 
    72     protected static final String INFO_NUM_SIBS = "numSiblings";
    73     protected static final String INFO_NUM_CHILDREN = "numChildren";
    74     protected static final String INFO_SIB_POS = "siblingPosition";
    75 
    76     // means the id is not a greenstone id and needs translating
    77     protected static final String EXTID_PARAM = "ext";
    78    
    79     protected Element config_info = null; // the xml from the config file
    80 
    81     protected String default_document_type = null;
    82     protected MacroResolver macro_resolver = null;
    83 
    84     /** does this class provide the service?? */
    85     protected boolean does_metadata = true;
    86     protected boolean does_content = true;
    87     protected boolean does_structure = true;
    88 
    89     /** constructor */
    90     public AbstractDocumentRetrieve()
    91     {
    92     }
    93 
    94     /** configure this service */
    95     public boolean configure(Element info, Element extra_info)
    96     {
    97     if (!super.configure(info, extra_info)){
    98         return false;
    99     }
    100 
    101     logger.info("Configuring AbstractDocumentRetrieve...");
    102     this.config_info = info;
    103 
    104     // set up short_service_info_ - for now just has name and type
    105     if (does_structure) {
    106         Element dsr_service = this.doc.createElement(GSXML.SERVICE_ELEM);
    107         dsr_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
    108         dsr_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_STRUCTURE_RETRIEVE_SERVICE);
    109         this.short_service_info.appendChild(dsr_service);
    110     }
    111 
    112     if (does_metadata) {
    113         Element dmr_service = this.doc.createElement(GSXML.SERVICE_ELEM);
    114         dmr_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
    115         dmr_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_METADATA_RETRIEVE_SERVICE);
    116         this.short_service_info.appendChild(dmr_service);
    117     }
    118 
    119     if (does_content) {
    120         Element dcr_service = this.doc.createElement(GSXML.SERVICE_ELEM);
    121         dcr_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
    122         dcr_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_CONTENT_RETRIEVE_SERVICE);
    123         this.short_service_info.appendChild(dcr_service);
    124     }
    125    
    126     // look for document display format
    127     String path = GSPath.appendLink(GSXML.DISPLAY_ELEM, GSXML.FORMAT_ELEM);
    128     Element display_format = (Element)GSXML.getNodeByPath(extra_info, path);
    129     if (display_format != null) {
    130         this.format_info_map.put(DOCUMENT_CONTENT_RETRIEVE_SERVICE, this.doc.importNode(display_format, true));
    131         // should we keep a copy?
    132         // check for docType option.
    133         Element doc_type_opt = GSXML.getNamedElement(display_format, "gsf:option", GSXML.NAME_ATT, "documentType");
    134         if (doc_type_opt != null) {
    135         String value = doc_type_opt.getAttribute(GSXML.VALUE_ATT);
    136         if (!value.equals("")) {
    137             this.default_document_type = value;
    138         }
    139         }
    140     }
    141      
    142     if (macro_resolver != null) {
    143         macro_resolver.setSiteDetails(this.site_http_address, this.cluster_name, this.getLibraryName());
    144         // set up the macro resolver
    145         Element replacement_elem = (Element)GSXML.getChildByTagName(extra_info, "replaceList");
    146         if (replacement_elem != null) {
    147         macro_resolver.addMacros(replacement_elem);
    148         }
    149         // look for any refs to global replace lists
    150         NodeList replace_refs_elems = extra_info.getElementsByTagName("replaceListRef");
    151         for (int i=0; i<replace_refs_elems.getLength(); i++) {
    152         String id = ((Element)replace_refs_elems.item(i)).getAttribute("id");
    153         if (!id.equals("")) {
    154             Element replace_list = GSXML.getNamedElement(this.router.config_info, "replaceList", "id", id);
    155             if (replace_list != null) {
    156             macro_resolver.addMacros(replace_list);
    157             }
    158         }
    159         }
    160     }
    161    
    162     return true;
    163     }
    164    
    165     protected Element getServiceDescription(String service_id, String lang, String subset) {
    166    
    167     // these ones are probably never called, but put them here just in case
    168     Element service_elem = this.doc.createElement(GSXML.SERVICE_ELEM);
    169     service_elem.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
    170     service_elem.setAttribute(GSXML.NAME_ATT, service_id);
    171     return service_elem;
    172     }
    173 
    174     protected Element processDocumentMetadataRetrieve(Element request) {
    175 
    176     // Create a new (empty) result message
    177     Element result = this.doc.createElement(GSXML.RESPONSE_ELEM);
    178     String lang = request.getAttribute(GSXML.LANG_ATT);
    179     result.setAttribute(GSXML.FROM_ATT, DOCUMENT_METADATA_RETRIEVE_SERVICE);
    180     result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
    181 
    182     if (!does_metadata) {
    183         // shouldn't get here
    184         return result;
    185     }
    186     // Get the parameters of the request
    187     Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
    188     if (param_list == null) {
    189         GSXML.addError(this.doc, result, "DocumentMetadataRetrieve: missing "+ GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER, GSXML.ERROR_TYPE_SYNTAX);
    190         return result; 
    191     }
    192 
    193     boolean external_id = false;
    194     // The metadata information required
    195     ArrayList metadata_names_list = new ArrayList();
    196     boolean all_metadata = false;
    197     // Process the request parameters
    198     Element param = GSXML.getFirstElementChild(param_list);//(Element) param_list.getFirstChild();
    199     while (param != null) {
    200         // Identify the metadata information desired
    201         if (param.getAttribute(GSXML.NAME_ATT).equals("metadata")) {
    202         String metadata = GSXML.getValue(param);
    203         if (metadata.equals("all")) {
    204             all_metadata = true;
    205             break;
    206         }
    207         metadata_names_list.add(metadata);
    208         } else if (param.getAttribute(GSXML.NAME_ATT).equals(EXTID_PARAM)&& GSXML.getValue(param).equals("1")) {
    209         external_id = true;
    210         }
    211         param = (Element) param.getNextSibling();
    212     }
    213 
    214     // check that there has been some metadata specified
    215     if (!all_metadata && metadata_names_list.size()==0) {
    216         GSXML.addError(this.doc, result, "DocumentMetadataRetrieve: no metadata names found in the "+ GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER, GSXML.ERROR_TYPE_SYNTAX);
    217         return result; 
    218     }
    219 
    220     // Get the documents
    221     Element request_node_list = (Element) GSXML.getChildByTagName(request, GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
    222     if (request_node_list == null) {
    223         GSXML.addError(this.doc, result, "DocumentMetadataRetrieve: missing " +GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER, GSXML.ERROR_TYPE_SYNTAX);
    224         return result;
    225     }
    226 
    227     // copy the request doc node list to the response
    228     Element response_node_list = (Element) this.doc.importNode(request_node_list, true);
    229     result.appendChild(response_node_list);
    230    
    231     // use the copied list so that we add the metadata into the copy
    232     // are we just adding metadata for the top level nodes? or can we accept a hierarchy here???
    233     NodeList request_nodes = GSXML.getChildrenByTagName(response_node_list, GSXML.DOC_NODE_ELEM);
    234     if (request_nodes.getLength()==0) {
    235         GSXML.addError(this.doc, result, "DocumentMetadataRetrieve: no "+GSXML.DOC_NODE_ELEM +" found in the "+ GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER, GSXML.ERROR_TYPE_SYNTAX);
    236         return result;
    237     }
    238 
    239     // Whew, now we have checked (almost) all the syntax of the request, now we can process it.
    240     for (int i = 0; i < request_nodes.getLength(); i++) {
    241         Element request_node = (Element) request_nodes.item(i);
    242         String node_id = request_node.getAttribute(GSXML.NODE_ID_ATT);
    243        
    244         boolean is_external_link = false;
    245         if (!node_id.startsWith("HASH") && !node_id.startsWith("D")){   
    246         if (node_id.endsWith(".rt")){
    247             node_id = getHrefOID(node_id.substring(0,node_id.length()-3));
    248             if (node_id!=null){
    249             node_id += ".rt";
    250             }else{
    251             is_external_link = true;
    252             }
    253         }else{
    254             node_id = getHrefOID(node_id);
    255             if (node_id==null){
    256             is_external_link = true;
    257             }
    258         }
    259         }
    260         if (!is_external_link){
    261         if (external_id) {
    262             // can we have .pr etc extensions with external ids?
    263             node_id = translateExternalId(node_id);
    264         } else if (idNeedsTranslating(node_id)) {
    265             node_id = translateId(node_id);
    266         }
    267         }
    268        
    269         if (node_id == null) {
    270         continue;
    271         }
    272         if (!is_external_link){
    273         try {
    274             Element metadata_list = getMetadataList(node_id, all_metadata, metadata_names_list);
    275             request_node.appendChild(metadata_list);
    276         } catch (GSException e) {       
    277             GSXML.addError(this.doc, result, e.getMessage(), e.getType());
    278             if (e.getType().equals(GSXML.ERROR_TYPE_SYSTEM)) {
    279             // there is no point trying any others
    280             return result;
    281             }
    282         }
    283         }else{
    284         request_node.setAttribute("external_link",request_node.getAttribute(GSXML.NODE_ID_ATT));
    285         }
    286     }
    287     return result;
    288     }
    289 
    290     protected Element processDocumentStructureRetrieve(Element request) {
    291    
    292     // Create a new (empty) result message
    293     Element result = this.doc.createElement(GSXML.RESPONSE_ELEM);
    294     result.setAttribute(GSXML.FROM_ATT, DOCUMENT_STRUCTURE_RETRIEVE_SERVICE);
    295     result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
    296    
    297     if (!does_structure) {
    298         // shouldn't get here
    299         return result;
    300     }
    301 
    302     String lang = request.getAttribute(GSXML.LANG_ATT);
    303 
    304     // Get the parameters of the request
    305     Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
    306     if (param_list == null) {
    307         GSXML.addError(this.doc, result, "DocumentStructureRetrieve: missing "+ GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER, GSXML.ERROR_TYPE_SYNTAX);
    308         return result; 
    309     }
    310    
    311     // get the documents of the request
    312     Element query_doc_list = (Element) GSXML.getChildByTagName(request, GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
    313     if (query_doc_list == null) {
    314         GSXML.addError(this.doc, result, "DocumentStructureRetrieve: missing " +GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER, GSXML.ERROR_TYPE_SYNTAX);
    315         return result;
    316     }
    317    
    318     // copy the doc_list to the response
    319     Element response_node_list = (Element) this.doc.importNode(query_doc_list, true);
    320     result.appendChild(response_node_list);
    321    
    322     // check that we have some doc nodes specified
    323     NodeList node_list = GSXML.getChildrenByTagName(response_node_list, GSXML.DOC_NODE_ELEM);
    324     if (node_list.getLength()==0) {
    325         GSXML.addError(this.doc, result, "DocumentStructureRetrieve: no "+GSXML.DOC_NODE_ELEM +" found in the "+ GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER, GSXML.ERROR_TYPE_SYNTAX);
    326         return result;
    327     }
    328 
    329     Element extid_param = GSXML.getNamedElement(param_list, GSXML.PARAM_ELEM, GSXML.NAME_ATT, EXTID_PARAM);
    330     boolean external_id = false;
    331     if (extid_param != null && GSXML.getValue(extid_param).equals("1")) {
    332         external_id = true;
    333     }
    334 
    335     // the type of info required
    336     boolean want_structure = false;
    337     boolean want_info = false;
    338 
    339     ArrayList info_types=new ArrayList();
    340     // The document structure information desired
    341     boolean want_ancestors = false;
    342     boolean want_parent = false;
    343     boolean want_siblings = false;
    344     boolean want_children = false;
    345     boolean want_descendants = false;
    346 
    347     boolean want_entire_structure = false;
    348     // Process the request parameters
    349     NodeList params = param_list.getElementsByTagName(GSXML.PARAM_ELEM);
    350     for (int i=0; i<params.getLength();i++) {
    351        
    352         Element param = (Element)params.item(i);
    353         String p_name = param.getAttribute(GSXML.NAME_ATT);
    354         String p_value = GSXML.getValue(param);
    355         // Identify the structure information desired
    356         if (p_name.equals(STRUCT_PARAM)) {
    357         want_structure = true;
    358        
    359         // This is NOT locale sensitive
    360         if (p_value.equals(STRUCT_ANCESTORS))
    361             want_ancestors = true;
    362         else if (p_value.equals(STRUCT_PARENT))
    363             want_parent = true;
    364         else if (p_value.equals(STRUCT_SIBS))
    365             want_siblings = true;
    366         else if (p_value.equals(STRUCT_CHILDREN))
    367             want_children = true;
    368         else if (p_value.equals(STRUCT_DESCENDS))
    369             want_descendants = true;
    370         else if (p_value.equals(STRUCT_ENTIRE))
    371             want_entire_structure = true;
     52public abstract class AbstractDocumentRetrieve extends ServiceRack
     53{
     54
     55    static Logger logger = Logger.getLogger(org.greenstone.gsdl3.service.AbstractDocumentRetrieve.class.getName());
     56
     57    // the services on offer
     58    protected static final String DOCUMENT_STRUCTURE_RETRIEVE_SERVICE = "DocumentStructureRetrieve";
     59    protected static final String DOCUMENT_METADATA_RETRIEVE_SERVICE = "DocumentMetadataRetrieve";
     60    protected static final String DOCUMENT_CONTENT_RETRIEVE_SERVICE = "DocumentContentRetrieve";
     61
     62    protected static final String STRUCT_PARAM = "structure";
     63    protected static final String INFO_PARAM = "info";
     64
     65    protected static final String STRUCT_ANCESTORS = "ancestors";
     66    protected static final String STRUCT_PARENT = "parent";
     67    protected static final String STRUCT_SIBS = "siblings";
     68    protected static final String STRUCT_CHILDREN = "children";
     69    protected static final String STRUCT_DESCENDS = "descendants";
     70    protected static final String STRUCT_ENTIRE = "entire";
     71
     72    protected static final String INFO_NUM_SIBS = "numSiblings";
     73    protected static final String INFO_NUM_CHILDREN = "numChildren";
     74    protected static final String INFO_SIB_POS = "siblingPosition";
     75
     76    // means the id is not a greenstone id and needs translating
     77    protected static final String EXTID_PARAM = "ext";
     78
     79    protected Element config_info = null; // the xml from the config file
     80
     81    protected String default_document_type = null;
     82    protected MacroResolver macro_resolver = null;
     83
     84    /** does this class provide the service?? */
     85    protected boolean does_metadata = true;
     86    protected boolean does_content = true;
     87    protected boolean does_structure = true;
     88
     89    /** constructor */
     90    public AbstractDocumentRetrieve()
     91    {
     92    }
     93
     94    /** configure this service */
     95    public boolean configure(Element info, Element extra_info)
     96    {
     97        if (!super.configure(info, extra_info))
     98        {
     99            return false;
     100        }
     101
     102        logger.info("Configuring AbstractDocumentRetrieve...");
     103        this.config_info = info;
     104
     105        // set up short_service_info_ - for now just has name and type
     106        if (does_structure)
     107        {
     108            Element dsr_service = this.doc.createElement(GSXML.SERVICE_ELEM);
     109            dsr_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
     110            dsr_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_STRUCTURE_RETRIEVE_SERVICE);
     111            this.short_service_info.appendChild(dsr_service);
     112        }
     113
     114        if (does_metadata)
     115        {
     116            Element dmr_service = this.doc.createElement(GSXML.SERVICE_ELEM);
     117            dmr_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
     118            dmr_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_METADATA_RETRIEVE_SERVICE);
     119            this.short_service_info.appendChild(dmr_service);
     120        }
     121
     122        if (does_content)
     123        {
     124            Element dcr_service = this.doc.createElement(GSXML.SERVICE_ELEM);
     125            dcr_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
     126            dcr_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_CONTENT_RETRIEVE_SERVICE);
     127            this.short_service_info.appendChild(dcr_service);
     128        }
     129
     130        // look for document display format
     131        String path = GSPath.appendLink(GSXML.DISPLAY_ELEM, GSXML.FORMAT_ELEM);
     132        Element display_format = (Element) GSXML.getNodeByPath(extra_info, path);
     133        if (display_format != null)
     134        {
     135            this.format_info_map.put(DOCUMENT_CONTENT_RETRIEVE_SERVICE, this.doc.importNode(display_format, true));
     136            // should we keep a copy?
     137            // check for docType option.
     138            Element doc_type_opt = GSXML.getNamedElement(display_format, "gsf:option", GSXML.NAME_ATT, "documentType");
     139            if (doc_type_opt != null)
     140            {
     141                String value = doc_type_opt.getAttribute(GSXML.VALUE_ATT);
     142                if (!value.equals(""))
     143                {
     144                    this.default_document_type = value;
     145                }
     146            }
     147        }
     148
     149        if (macro_resolver != null)
     150        {
     151            macro_resolver.setSiteDetails(this.site_http_address, this.cluster_name, this.getLibraryName());
     152            // set up the macro resolver
     153            Element replacement_elem = (Element) GSXML.getChildByTagName(extra_info, "replaceList");
     154            if (replacement_elem != null)
     155            {
     156                macro_resolver.addMacros(replacement_elem);
     157            }
     158            // look for any refs to global replace lists
     159            NodeList replace_refs_elems = extra_info.getElementsByTagName("replaceListRef");
     160            for (int i = 0; i < replace_refs_elems.getLength(); i++)
     161            {
     162                String id = ((Element) replace_refs_elems.item(i)).getAttribute("id");
     163                if (!id.equals(""))
     164                {
     165                    Element replace_list = GSXML.getNamedElement(this.router.config_info, "replaceList", "id", id);
     166                    if (replace_list != null)
     167                    {
     168                        macro_resolver.addMacros(replace_list);
     169                    }
     170                }
     171            }
     172        }
     173
     174        return true;
     175    }
     176
     177    protected Element getServiceDescription(String service_id, String lang, String subset)
     178    {
     179
     180        // these ones are probably never called, but put them here just in case
     181        Element service_elem = this.doc.createElement(GSXML.SERVICE_ELEM);
     182        service_elem.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
     183        service_elem.setAttribute(GSXML.NAME_ATT, service_id);
     184        return service_elem;
     185    }
     186
     187    protected Element processDocumentMetadataRetrieve(Element request)
     188    {
     189
     190        // Create a new (empty) result message
     191        Element result = this.doc.createElement(GSXML.RESPONSE_ELEM);
     192        String lang = request.getAttribute(GSXML.LANG_ATT);
     193        result.setAttribute(GSXML.FROM_ATT, DOCUMENT_METADATA_RETRIEVE_SERVICE);
     194        result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
     195
     196        if (!does_metadata)
     197        {
     198            // shouldn't get here
     199            return result;
     200        }
     201        // Get the parameters of the request
     202        Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
     203        if (param_list == null)
     204        {
     205            GSXML.addError(this.doc, result, "DocumentMetadataRetrieve: missing " + GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER, GSXML.ERROR_TYPE_SYNTAX);
     206            return result;
     207        }
     208
     209        boolean external_id = false;
     210        // The metadata information required
     211        ArrayList metadata_names_list = new ArrayList();
     212        boolean all_metadata = false;
     213        // Process the request parameters
     214        Element param = GSXML.getFirstElementChild(param_list);//(Element) param_list.getFirstChild();
     215        while (param != null)
     216        {
     217            // Identify the metadata information desired
     218            if (param.getAttribute(GSXML.NAME_ATT).equals("metadata"))
     219            {
     220                String metadata = GSXML.getValue(param);
     221                if (metadata.equals("all"))
     222                {
     223                    all_metadata = true;
     224                    break;
     225                }
     226                metadata_names_list.add(metadata);
     227            }
     228            else if (param.getAttribute(GSXML.NAME_ATT).equals(EXTID_PARAM) && GSXML.getValue(param).equals("1"))
     229            {
     230                external_id = true;
     231            }
     232            param = (Element) param.getNextSibling();
     233        }
     234
     235        // check that there has been some metadata specified
     236        if (!all_metadata && metadata_names_list.size() == 0)
     237        {
     238            GSXML.addError(this.doc, result, "DocumentMetadataRetrieve: no metadata names found in the " + GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER, GSXML.ERROR_TYPE_SYNTAX);
     239            return result;
     240        }
     241
     242        // Get the documents
     243        Element request_node_list = (Element) GSXML.getChildByTagName(request, GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER);
     244        if (request_node_list == null)
     245        {
     246            GSXML.addError(this.doc, result, "DocumentMetadataRetrieve: missing " + GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER, GSXML.ERROR_TYPE_SYNTAX);
     247            return result;
     248        }
     249
     250        // copy the request doc node list to the response
     251        Element response_node_list = (Element) this.doc.importNode(request_node_list, true);
     252        result.appendChild(response_node_list);
     253
     254        // use the copied list so that we add the metadata into the copy
     255        // are we just adding metadata for the top level nodes? or can we accept a hierarchy here???
     256        NodeList request_nodes = GSXML.getChildrenByTagName(response_node_list, GSXML.DOC_NODE_ELEM);
     257        if (request_nodes.getLength() == 0)
     258        {
     259            GSXML.addError(this.doc, result, "DocumentMetadataRetrieve: no " + GSXML.DOC_NODE_ELEM + " found in the " + GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER, GSXML.ERROR_TYPE_SYNTAX);
     260            return result;
     261        }
     262
     263        // Whew, now we have checked (almost) all the syntax of the request, now we can process it.
     264        for (int i = 0; i < request_nodes.getLength(); i++)
     265        {
     266            Element request_node = (Element) request_nodes.item(i);
     267            String node_id = request_node.getAttribute(GSXML.NODE_ID_ATT);
     268
     269            boolean is_external_link = false;
     270            if (!node_id.startsWith("HASH") && !node_id.startsWith("D"))
     271            {
     272                if (node_id.endsWith(".rt"))
     273                {
     274                    node_id = getHrefOID(node_id.substring(0, node_id.length() - 3));
     275                    if (node_id != null)
     276                    {
     277                        node_id += ".rt";
     278                    }
     279                    else
     280                    {
     281                        is_external_link = true;
     282                    }
     283                }
     284                else
     285                {
     286                    node_id = getHrefOID(node_id);
     287                    if (node_id == null)
     288                    {
     289                        is_external_link = true;
     290                    }
     291                }
     292            }
     293            if (!is_external_link)
     294            {
     295                if (external_id)
     296                {
     297                    // can we have .pr etc extensions with external ids?
     298                    node_id = translateExternalId(node_id);
     299                }
     300                else if (idNeedsTranslating(node_id))
     301                {
     302                    node_id = translateId(node_id);
     303                }
     304            }
     305
     306            if (node_id == null)
     307            {
     308                continue;
     309            }
     310            if (!is_external_link)
     311            {
     312                try
     313                {
     314                    Element metadata_list = getMetadataList(node_id, all_metadata, metadata_names_list);
     315                    request_node.appendChild(metadata_list);
     316                }
     317                catch (GSException e)
     318                {
     319                    GSXML.addError(this.doc, result, e.getMessage(), e.getType());
     320                    if (e.getType().equals(GSXML.ERROR_TYPE_SYSTEM))
     321                    {
     322                        // there is no point trying any others
     323                        return result;
     324                    }
     325                }
     326            }
     327            else
     328            {
     329                request_node.setAttribute("external_link", request_node.getAttribute(GSXML.NODE_ID_ATT));
     330            }
     331        }
     332        return result;
     333    }
     334
     335    protected Element processDocumentStructureRetrieve(Element request)
     336    {
     337
     338        // Create a new (empty) result message
     339        Element result = this.doc.createElement(GSXML.RESPONSE_ELEM);
     340        result.setAttribute(GSXML.FROM_ATT, DOCUMENT_STRUCTURE_RETRIEVE_SERVICE);
     341        result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
     342
     343        if (!does_structure)
     344        {
     345            // shouldn't get here
     346            return result;
     347        }
     348
     349        String lang = request.getAttribute(GSXML.LANG_ATT);
     350
     351        // Get the parameters of the request
     352        Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
     353        if (param_list == null)
     354        {
     355            GSXML.addError(this.doc, result, "DocumentStructureRetrieve: missing " + GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER, GSXML.ERROR_TYPE_SYNTAX);
     356            return result;
     357        }
     358
     359        // get the documents of the request
     360        Element query_doc_list = (Element) GSXML.getChildByTagName(request, GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER);
     361        if (query_doc_list == null)
     362        {
     363            GSXML.addError(this.doc, result, "DocumentStructureRetrieve: missing " + GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER, GSXML.ERROR_TYPE_SYNTAX);
     364            return result;
     365        }
     366
     367        // copy the doc_list to the response
     368        Element response_node_list = (Element) this.doc.importNode(query_doc_list, true);
     369        result.appendChild(response_node_list);
     370
     371        // check that we have some doc nodes specified
     372        NodeList node_list = GSXML.getChildrenByTagName(response_node_list, GSXML.DOC_NODE_ELEM);
     373        if (node_list.getLength() == 0)
     374        {
     375            GSXML.addError(this.doc, result, "DocumentStructureRetrieve: no " + GSXML.DOC_NODE_ELEM + " found in the " + GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER, GSXML.ERROR_TYPE_SYNTAX);
     376            return result;
     377        }
     378
     379        Element extid_param = GSXML.getNamedElement(param_list, GSXML.PARAM_ELEM, GSXML.NAME_ATT, EXTID_PARAM);
     380        boolean external_id = false;
     381        if (extid_param != null && GSXML.getValue(extid_param).equals("1"))
     382        {
     383            external_id = true;
     384        }
     385
     386        // the type of info required
     387        boolean want_structure = false;
     388        boolean want_info = false;
     389
     390        ArrayList info_types = new ArrayList();
     391        // The document structure information desired
     392        boolean want_ancestors = false;
     393        boolean want_parent = false;
     394        boolean want_siblings = false;
     395        boolean want_children = false;
     396        boolean want_descendants = false;
     397
     398        boolean want_entire_structure = false;
     399        // Process the request parameters
     400        NodeList params = param_list.getElementsByTagName(GSXML.PARAM_ELEM);
     401        for (int i = 0; i < params.getLength(); i++)
     402        {
     403
     404            Element param = (Element) params.item(i);
     405            String p_name = param.getAttribute(GSXML.NAME_ATT);
     406            String p_value = GSXML.getValue(param);
     407            // Identify the structure information desired
     408            if (p_name.equals(STRUCT_PARAM))
     409            {
     410                want_structure = true;
     411
     412                // This is NOT locale sensitive
     413                if (p_value.equals(STRUCT_ANCESTORS))
     414                    want_ancestors = true;
     415                else if (p_value.equals(STRUCT_PARENT))
     416                    want_parent = true;
     417                else if (p_value.equals(STRUCT_SIBS))
     418                    want_siblings = true;
     419                else if (p_value.equals(STRUCT_CHILDREN))
     420                    want_children = true;
     421                else if (p_value.equals(STRUCT_DESCENDS))
     422                    want_descendants = true;
     423                else if (p_value.equals(STRUCT_ENTIRE))
     424                    want_entire_structure = true;
     425                else
     426                    logger.error("AbstractDocumentRetrieve Warning: Unknown value \"" + p_value + "\".");
     427            }
     428            else if (p_name.equals(INFO_PARAM))
     429            {
     430                want_info = true;
     431                info_types.add(p_value);
     432            }
     433        }
     434
     435        // Make sure there is no repeated information
     436        if (want_ancestors)
     437            want_parent = false;
     438        if (want_descendants)
     439            want_children = false;
     440
     441        for (int i = 0; i < node_list.getLength(); i++)
     442        {
     443            Element doc = (Element) node_list.item(i);
     444            String doc_id = doc.getAttribute(GSXML.NODE_ID_ATT);
     445            String is_external = doc.getAttribute("externalURL");
     446
     447            boolean is_external_link = false;
     448            if (is_external.equals("0"))
     449            {
     450                is_external_link = true;
     451            }
     452            if (is_external.equals("1") && !doc_id.startsWith("HASH") && !is_external_link)
     453            {
     454                if (doc_id.endsWith(".rt"))
     455                {
     456                    doc_id = getHrefOID(doc_id.substring(0, doc_id.length() - 3));
     457                    if (doc_id != null)
     458                    {
     459                        doc_id += ".rt";
     460                    }
     461                    else
     462                    {
     463                        is_external_link = true;
     464                    }
     465                }
     466                else
     467                {
     468                    doc_id = getHrefOID(doc_id);
     469                    if (doc_id == null)
     470                    {
     471                        is_external_link = true;
     472                    }
     473                }
     474            }
     475            if (!is_external_link)
     476            {
     477                if (external_id)
     478                {
     479                    doc_id = translateExternalId(doc_id);
     480                    doc.setAttribute(GSXML.NODE_ID_ATT, doc_id);
     481                }
     482                else if (idNeedsTranslating(doc_id))
     483                {
     484                    doc_id = translateId(doc_id);
     485                    doc.setAttribute(GSXML.NODE_ID_ATT, doc_id);
     486                }
     487
     488                if (doc_id == null)
     489                {
     490                    continue;
     491                }
     492
     493                if (want_info)
     494                {
     495
     496                    Element node_info_elem = this.doc.createElement("nodeStructureInfo");
     497                    doc.appendChild(node_info_elem);
     498
     499                    for (int j = 0; j < info_types.size(); j++)
     500                    {
     501                        String info_type = (String) info_types.get(j);
     502                        String info_value = getStructureInfo(doc_id, info_type);
     503                        if (info_value != null)
     504                        {
     505                            Element info_elem = this.doc.createElement("info");
     506                            info_elem.setAttribute(GSXML.NAME_ATT, info_type);
     507                            info_elem.setAttribute(GSXML.VALUE_ATT, info_value);
     508                            node_info_elem.appendChild(info_elem);
     509                        }
     510                    }
     511                }
     512
     513                if (want_structure)
     514                {
     515                    // all structure info goes into a nodeStructure elem
     516                    Element structure_elem = this.doc.createElement(GSXML.NODE_STRUCTURE_ELEM);
     517                    doc.appendChild(structure_elem);
     518
     519                    if (want_entire_structure)
     520                    {
     521                        String root_id = getRootId(doc_id);
     522                        Element root_node = createDocNode(root_id); //, true, false);
     523                        addDescendants(root_node, root_id, true);
     524                        structure_elem.appendChild(root_node);
     525                        continue; // with the next document, we dont need to do any more here
     526                    }
     527
     528                    // Add the requested structure information
     529                    Element base_node = createDocNode(doc_id); //, false, false);
     530
     531                    //Ancestors: continually add parent nodes until the root is reached
     532                    Element top_node = base_node; // the top node so far
     533                    if (want_ancestors)
     534                    {
     535                        String current_id = doc_id;
     536                        while (true)
     537                        {
     538                            String parent_id = getParentId(current_id);
     539                            //Element parent = getParent(current_id);
     540                            if (parent_id == null)
     541                                break; // no parent
     542                            Element parent_node = createDocNode(parent_id);
     543                            parent_node.appendChild(top_node);
     544                            current_id = parent_id;//.getAttribute(GSXML.NODE_ID_ATT);
     545                            top_node = parent_node;
     546                        }
     547                    }
     548                    // Parent: get the parent of the selected node
     549                    else if (want_parent)
     550                    {
     551                        String parent_id = getParentId(doc_id);
     552                        if (parent_id != null)
     553                        {
     554                            Element parent_node = createDocNode(parent_id);
     555                            parent_node.appendChild(base_node);
     556                            top_node = parent_node;
     557                        }
     558                    }
     559
     560                    // now the top node is the root of the structure
     561                    structure_elem.appendChild(top_node);
     562
     563                    //Siblings: get the other descendants of the selected node's parent
     564                    if (want_siblings)
     565                    {
     566                        String parent_id = getParentId(doc_id);
     567                        if (parent_id != null)
     568                        {
     569                            // if parent == current id, then we are at the top
     570                            // and can't get siblings
     571                            Element parent_node = (Element) base_node.getParentNode(); // this may be the structure element if there has been no request for parents or ancestors
     572
     573                            // add siblings, - returns a pointer to the new current node
     574                            base_node = addSiblings(parent_node, parent_id, doc_id);
     575                        }
     576
     577                    }
     578
     579                    // Children: get the descendants, but only one level deep
     580                    if (want_children)
     581                    {
     582                        addDescendants(base_node, doc_id, false);
     583                    }
     584                    // Descendants: recursively get every descendant
     585                    else if (want_descendants)
     586                    {
     587                        addDescendants(base_node, doc_id, true);
     588                    }
     589                } // if want structure
     590
     591            }
     592            else
     593            {
     594                Element external_link_elem = this.doc.createElement("external");
     595                external_link_elem.setAttribute("external_link", doc.getAttribute(GSXML.NODE_ID_ATT));
     596                doc.appendChild(external_link_elem);
     597            }// if is_external_link
     598        } // for each doc
     599        return result;
     600    }
     601
     602    /** Retrieve the content of a document */
     603    protected Element processDocumentContentRetrieve(Element request)
     604    {
     605        // Create a new (empty) result message
     606        Element result = this.doc.createElement(GSXML.RESPONSE_ELEM);
     607        result.setAttribute(GSXML.FROM_ATT, DOCUMENT_CONTENT_RETRIEVE_SERVICE);
     608        result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
     609
     610        if (!does_content)
     611        {
     612            // shouldn't get here
     613            return result;
     614        }
     615
     616        // Get the parameters of the request
     617        Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
     618        Element extid_param = GSXML.getNamedElement(param_list, GSXML.PARAM_ELEM, GSXML.NAME_ATT, EXTID_PARAM);
     619        boolean external_id = false;
     620        if (extid_param != null && GSXML.getValue(extid_param).equals("1"))
     621        {
     622            external_id = true;
     623        }
     624        // Get the request content
     625        Element query_doc_list = (Element) GSXML.getChildByTagName(request, GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER);
     626        if (query_doc_list == null)
     627        {
     628            logger.error("Error: DocumentContentRetrieve request specified no doc nodes.\n");
     629            return result;
     630        }
     631
     632        String lang = request.getAttribute(GSXML.LANG_ATT);
     633        Element doc_list = this.doc.createElement(GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER);
     634        result.appendChild(doc_list);
     635
     636        // set up the retrieval??
     637
     638        // Get the documents
     639        String[] doc_ids = GSXML.getAttributeValuesFromList(query_doc_list, GSXML.NODE_ID_ATT);
     640        String[] is_externals = GSXML.getAttributeValuesFromList(query_doc_list, "externalURL");
     641
     642        for (int i = 0; i < doc_ids.length; i++)
     643        {
     644            String doc_id = doc_ids[i];
     645            String is_external = is_externals[i];
     646
     647            boolean is_external_link = false;
     648            if (is_external.equals("0"))
     649            {
     650                is_external_link = true;
     651            }
     652            if (is_external.equals("1") && !doc_id.startsWith("HASH") && !is_external_link)
     653            {
     654                //if (!doc_id.startsWith("HASH")){
     655                if (doc_id.endsWith(".rt"))
     656                {
     657                    String find_doc_id = getHrefOID(doc_id.substring(0, doc_id.length() - 3));
     658                    if (find_doc_id != null)
     659                    {
     660                        doc_id = doc_id + ".rt";
     661                    }
     662                    else
     663                    {
     664                        is_external_link = true;
     665                    }
     666
     667                }
     668                else
     669                {
     670                    String find_doc_id = getHrefOID(doc_id);
     671                    if (find_doc_id == null)
     672                    {
     673                        is_external_link = true;
     674                    }
     675                    else
     676                    {
     677                        doc_id = find_doc_id;
     678                    }
     679                }
     680            }
     681
     682            if (!is_external_link)
     683            {
     684                // Create the document node
     685                Element doc = this.doc.createElement(GSXML.DOC_NODE_ELEM);
     686                doc.setAttribute(GSXML.NODE_ID_ATT, doc_id);
     687                doc_list.appendChild(doc);
     688
     689                if (external_id)
     690                {
     691                    doc_id = translateExternalId(doc_id);
     692                    doc.setAttribute(GSXML.NODE_ID_ATT, doc_id);
     693                }
     694                else if (idNeedsTranslating(doc_id))
     695                {
     696                    doc_id = translateId(doc_id);
     697                    doc.setAttribute(GSXML.NODE_ID_ATT, doc_id);
     698                }
     699                if (doc_id == null)
     700                {
     701                    continue;
     702                }
     703                try
     704                {
     705                    Element node_content = getNodeContent(doc_id, lang);
     706                    doc.appendChild(node_content);
     707                }
     708                catch (GSException e)
     709                {
     710                    GSXML.addError(this.doc, result, e.getMessage());
     711                    return result;
     712
     713                }
     714            }
     715            else
     716            {
     717                Element doc = this.doc.createElement(GSXML.DOC_NODE_ELEM);
     718                doc.setAttribute(GSXML.NODE_ID_ATT, doc_id);
     719                //doc.setAttribute("external_link", doc_id);
     720                Element external_link_elem = this.doc.createElement("external");
     721                external_link_elem.setAttribute("external_link", doc_id);
     722                doc.appendChild(external_link_elem);
     723
     724                doc_list.appendChild(doc);
     725            }
     726        }
     727        return result;
     728    }
     729
     730    /**
     731     * create an element to go into the structure. A node element has the form
     732     * <docNode nodeId='xxx' nodeType='leaf' docType='hierarchy'/>
     733     */
     734    protected Element createDocNode(String node_id)
     735    {
     736        Element node = this.doc.createElement(GSXML.DOC_NODE_ELEM);
     737        node.setAttribute(GSXML.NODE_ID_ATT, node_id);
     738
     739        String doc_type = null;
     740        if (default_document_type != null)
     741        {
     742            doc_type = default_document_type;
     743        }
    372744        else
    373             logger.error("AbstractDocumentRetrieve Warning: Unknown value \"" + p_value + "\".");
    374         } else if (p_name.equals(INFO_PARAM)) {
    375         want_info = true;
    376         info_types.add(p_value);
    377         }
    378     }
    379 
    380     // Make sure there is no repeated information
    381     if (want_ancestors)
    382         want_parent = false;
    383     if (want_descendants)
    384         want_children = false;
    385 
    386     for (int i=0; i < node_list.getLength(); i++) {
    387         Element doc = (Element) node_list.item(i);
    388         String doc_id = doc.getAttribute(GSXML.NODE_ID_ATT);
    389         String is_external=doc.getAttribute("externalURL");
    390 
    391         boolean is_external_link = false;
    392         if (is_external.equals("0")) {is_external_link = true;}
    393         if (is_external.equals("1") && !doc_id.startsWith("HASH") && !is_external_link){
    394         if (doc_id.endsWith(".rt")){
    395             doc_id = getHrefOID(doc_id.substring(0,doc_id.length()-3));
    396             if (doc_id!=null){
    397             doc_id += ".rt";
    398             }else{
    399             is_external_link = true;
    400             }
    401         }else{
    402             doc_id = getHrefOID(doc_id);
    403             if (doc_id==null){ is_external_link = true;}
    404         }
    405         }
    406         if (!is_external_link){
    407         if (external_id) {
    408             doc_id = translateExternalId(doc_id);
    409             doc.setAttribute(GSXML.NODE_ID_ATT, doc_id);
    410         } else if (idNeedsTranslating(doc_id)) {
    411             doc_id = translateId(doc_id);   
    412             doc.setAttribute(GSXML.NODE_ID_ATT, doc_id);
    413         }
    414        
    415         if (doc_id == null) {
    416         continue;
    417         }
    418 
    419         if (want_info) {
    420 
    421         Element node_info_elem = this.doc.createElement("nodeStructureInfo");
    422         doc.appendChild(node_info_elem);
    423        
    424         for (int j=0; j<info_types.size(); j++) {
    425             String info_type = (String)info_types.get(j);
    426             String info_value = getStructureInfo(doc_id, info_type);
    427             if (info_value != null) {
    428             Element info_elem = this.doc.createElement("info");
    429             info_elem.setAttribute(GSXML.NAME_ATT, info_type);
    430             info_elem.setAttribute(GSXML.VALUE_ATT, info_value);
    431             node_info_elem.appendChild(info_elem);
    432             }
    433         }
    434         }
    435        
    436         if (want_structure) {
    437         // all structure info goes into a nodeStructure elem
    438         Element structure_elem = this.doc.createElement(GSXML.NODE_STRUCTURE_ELEM);
    439         doc.appendChild(structure_elem);
    440        
    441         if (want_entire_structure) {
    442             String root_id = getRootId(doc_id);
    443             Element root_node = createDocNode(root_id); //, true, false);
    444             addDescendants(root_node, root_id, true);
    445             structure_elem.appendChild(root_node);
    446             continue; // with the next document, we dont need to do any more here
    447         }
    448        
    449         // Add the requested structure information
    450         Element base_node = createDocNode(doc_id); //, false, false);
    451        
    452         //Ancestors: continually add parent nodes until the root is reached
    453         Element top_node = base_node; // the top node so far
    454         if (want_ancestors) {
    455             String current_id = doc_id;
    456             while (true) {
    457             String parent_id = getParentId(current_id);
    458             //Element parent = getParent(current_id);
    459             if (parent_id == null)
    460                 break; // no parent
    461             Element parent_node = createDocNode(parent_id);
    462             parent_node.appendChild(top_node);
    463             current_id = parent_id;//.getAttribute(GSXML.NODE_ID_ATT);
    464             top_node = parent_node;
    465             }
    466         }
    467         // Parent: get the parent of the selected node
    468         else if (want_parent) {
    469             String parent_id = getParentId(doc_id);
    470             if (parent_id != null) {
    471             Element parent_node = createDocNode(parent_id);
    472             parent_node.appendChild(base_node);
    473             top_node = parent_node;
    474             }
    475         }
    476        
    477         // now the top node is the root of the structure
    478         structure_elem.appendChild(top_node);
    479        
    480         //Siblings: get the other descendants of the selected node's parent
    481         if (want_siblings) {
    482             String parent_id = getParentId(doc_id);
    483             if (parent_id != null) {
    484             // if parent == current id, then we are at the top
    485             // and can't get siblings
    486             Element parent_node = (Element)base_node.getParentNode(); // this may be the structure element if there has been no request for parents or ancestors
    487            
    488             // add siblings, - returns a pointer to the new current node
    489             base_node = addSiblings(parent_node, parent_id, doc_id);
    490             }
    491 
    492         }
    493        
    494         // Children: get the descendants, but only one level deep
    495         if (want_children) {
    496             addDescendants(base_node, doc_id, false);
    497         }
    498         // Descendants: recursively get every descendant
    499         else if (want_descendants) {
    500             addDescendants(base_node, doc_id, true);
    501         }
    502         } // if want structure
    503 
    504         }else{
    505         Element external_link_elem = this.doc.createElement("external");
    506         external_link_elem.setAttribute("external_link",doc.getAttribute(GSXML.NODE_ID_ATT));
    507         doc.appendChild(external_link_elem);
    508         }// if is_external_link
    509     } // for each doc
    510     return result;
    511     }
    512 
    513     /** Retrieve the content of a document */
    514     protected Element processDocumentContentRetrieve(Element request)
    515     {
    516     // Create a new (empty) result message
    517     Element result = this.doc.createElement(GSXML.RESPONSE_ELEM);
    518     result.setAttribute(GSXML.FROM_ATT, DOCUMENT_CONTENT_RETRIEVE_SERVICE);
    519     result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
    520    
    521     if (!does_content) {
    522         // shouldn't get here
    523         return result;
    524     }
    525 
    526     // Get the parameters of the request
    527     Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
    528     Element extid_param = GSXML.getNamedElement(param_list, GSXML.PARAM_ELEM, GSXML.NAME_ATT, EXTID_PARAM);
    529     boolean external_id = false;
    530     if (extid_param != null && GSXML.getValue(extid_param).equals("1")) {
    531         external_id = true;
    532     }
    533     // Get the request content
    534     Element query_doc_list = (Element) GSXML.getChildByTagName(request, GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
    535     if (query_doc_list == null) {
    536         logger.error("Error: DocumentContentRetrieve request specified no doc nodes.\n");
    537         return result;
    538     }
    539    
    540     String lang = request.getAttribute(GSXML.LANG_ATT);
    541     Element doc_list = this.doc.createElement(GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
    542     result.appendChild(doc_list);
    543    
    544     // set up the retrieval??
    545 
    546     // Get the documents
    547     String[] doc_ids = GSXML.getAttributeValuesFromList(query_doc_list,
    548                                 GSXML.NODE_ID_ATT);
    549     String[] is_externals=GSXML.getAttributeValuesFromList(query_doc_list,"externalURL");
    550 
    551     for (int i = 0; i < doc_ids.length; i++) {
    552         String doc_id = doc_ids[i];
    553         String is_external=is_externals[i];
    554 
    555         boolean is_external_link=false;
    556         if (is_external.equals("0")){is_external_link = true;}
    557         if (is_external.equals("1") && !doc_id.startsWith("HASH") && !is_external_link){
    558         //if (!doc_id.startsWith("HASH")){
    559         if (doc_id.endsWith(".rt")){
    560             String find_doc_id = getHrefOID(doc_id.substring(0,doc_id.length()-3));
    561             if (find_doc_id!=null){
    562             doc_id = doc_id + ".rt";
    563             }else{
    564             is_external_link=true; 
    565             }
    566            
    567         }else {
    568             String find_doc_id = getHrefOID(doc_id);
    569             if (find_doc_id==null){
    570             is_external_link=true;
    571             }else{
    572             doc_id = find_doc_id;
    573             }
    574         }
    575         }
    576 
    577         if (!is_external_link){
    578         // Create the document node
    579         Element doc = this.doc.createElement(GSXML.DOC_NODE_ELEM);
    580         doc.setAttribute(GSXML.NODE_ID_ATT, doc_id);
    581         doc_list.appendChild(doc);
    582 
    583         if (external_id) {
    584         doc_id = translateExternalId(doc_id);
    585         doc.setAttribute(GSXML.NODE_ID_ATT, doc_id);
    586         } else if (idNeedsTranslating(doc_id)) {
    587         doc_id = translateId(doc_id);
    588         doc.setAttribute(GSXML.NODE_ID_ATT, doc_id);
    589         }
    590         if (doc_id == null) {
    591         continue;
    592         }
    593         try {
    594         Element node_content = getNodeContent(doc_id, lang);
    595         doc.appendChild(node_content);
    596         } catch (GSException e) {
    597         GSXML.addError(this.doc, result, e.getMessage());
    598         return result;
    599        
    600         }
    601         }else{
    602          Element doc = this.doc.createElement(GSXML.DOC_NODE_ELEM);
    603          doc.setAttribute(GSXML.NODE_ID_ATT, doc_id);
    604          //doc.setAttribute("external_link", doc_id);
    605          Element external_link_elem = this.doc.createElement("external");
    606          external_link_elem.setAttribute("external_link",doc_id);
    607          doc.appendChild(external_link_elem);
    608 
    609          doc_list.appendChild(doc);
    610         }
    611     }
    612     return result;
    613     }
    614    
    615     /** create an element to go into the structure. A node element
    616      * has the form
    617      * <docNode nodeId='xxx' nodeType='leaf' docType='hierarchy'/>
    618      */
    619     protected Element createDocNode(String node_id) {
    620     Element node = this.doc.createElement(GSXML.DOC_NODE_ELEM);
    621     node.setAttribute(GSXML.NODE_ID_ATT, node_id);
    622 
    623     String doc_type = null;
    624     if (default_document_type != null) {
    625         doc_type = default_document_type;
    626     } else {
    627         doc_type = getDocType(node_id);
    628     }
    629     node.setAttribute(GSXML.DOC_TYPE_ATT, doc_type);
    630     String node_type = getNodeType(node_id, doc_type); 
    631     node.setAttribute(GSXML.NODE_TYPE_ATT, node_type);
    632     return node;
    633     }
    634 
    635     /** adds all the children of doc_id the the doc element,
    636      * and if recursive=true, adds all their children as well*/
    637     protected void addDescendants(Element doc, String doc_id,
    638                   boolean recursive)
    639     {
    640     ArrayList child_ids = getChildrenIds(doc_id);
    641     if (child_ids==null) return;
    642     for (int i=0; i< child_ids.size(); i++) {
    643         String child_id = (String)child_ids.get(i);
    644         Element child_elem = createDocNode(child_id);
    645         doc.appendChild(child_elem);
    646         if (recursive && !child_elem.getAttribute(GSXML.NODE_TYPE_ATT).equals(GSXML.NODE_TYPE_LEAF)) {
    647         addDescendants(child_elem, child_id, recursive);
    648         }
    649     }
    650     }
    651 
    652     /** adds all the siblings of current_id to the parent element.
    653       returns the new current element*/
    654     protected Element addSiblings(Element parent_node, String parent_id,
    655                   String current_id) {
    656     Element current_node = GSXML.getFirstElementChild(parent_node);//(Element)parent_node.getFirstChild();
    657     if (current_node == null) {
    658         // create a sensible error message
    659         logger.error(" there should be a first child.");
    660         return null;
    661     }
    662     // remove the current child,- will add it in later in its correct place
    663     parent_node.removeChild(current_node);
    664 
    665     // add in all the siblings,
    666     addDescendants(parent_node, parent_id, false);
    667 
    668     // find the node that is now the current node
    669     // this assumes that the new node that was created is the same as
    670     // the old one that was removed - we may want to replace the new one
    671     // with the old one.
    672     Element new_current = GSXML.getNamedElement(parent_node, current_node.getNodeName(), GSXML.NODE_ID_ATT, current_id);
    673     return new_current;
    674     }
    675 
    676     /** returns true if oid ends in
    677     .fc (firstchild),
    678     .lc (lastchild),
    679     .pr (parent),
    680     .ns (next sibling),
    681     .ps (prev sibling),
    682     .rt (root)
    683     .ss (specified sibling),
    684     false otherwise
    685     */
    686     protected boolean idNeedsTranslating(String id) {
    687     return OID.needsTranslating(id);
    688     }
    689 
    690     /** returns the list of sibling ids, including the specified node_id */
    691     protected ArrayList getSiblingIds(String node_id) {
    692     String parent_id = getParentId(node_id);
    693     if (parent_id == null) {
    694         return null;
    695     }
    696     return getChildrenIds(parent_id);
    697 
    698     }
    699 
    700    /** returns the node type of the specified node.
    701     should be one of
    702     GSXML.NODE_TYPE_LEAF,
    703     GSXML.NODE_TYPE_INTERNAL,
    704     GSXML.NODE_TYPE_ROOT
    705     */
    706     protected String getNodeType(String node_id, String doc_type) {
    707     if (doc_type.equals(GSXML.DOC_TYPE_SIMPLE)) {
    708         return GSXML.NODE_TYPE_LEAF;
    709     }
    710 
    711     if (getParentId(node_id)==null) {
    712         return GSXML.NODE_TYPE_ROOT;
    713     }
    714     if (doc_type.equals(GSXML.DOC_TYPE_PAGED)) {
    715          return GSXML.NODE_TYPE_LEAF;
    716     }
    717     if (getChildrenIds(node_id)==null) {
    718         return GSXML.NODE_TYPE_LEAF;
    719     }
    720     return GSXML.NODE_TYPE_INTERNAL;   
    721    
    722     }
    723 
    724     /** if id ends in .fc, .pc etc, then translate it to the correct id
    725      * default implementation: just remove the suffix */
    726     protected String translateId(String id) {
    727     return id.substring(0,id.length());
    728     }
    729    
    730     /** if an id is not a greenstone id (an external id) then translate
    731      * it to a greenstone one
    732      * default implementation: return the id */
    733     protected String translateExternalId(String id) {
    734     return id;
    735     }
    736 
    737     /** returns the document type of the doc that the specified node
    738     belongs to. should be one of
    739     GSXML.DOC_TYPE_SIMPLE,
    740     GSXML.DOC_TYPE_PAGED,
    741     GSXML.DOC_TYPE_HIERARCHY
    742     default implementation: return DOC_TYPE_SIMPLE
    743     */
    744     protected String getDocType(String node_id) {
    745     return GSXML.DOC_TYPE_SIMPLE;
    746     }
    747    
    748 
    749     /** returns the id of the root node of the document containing
    750      * node node_id. may be the same as node_id
    751      * default implemntation: return node_id
    752     */
    753     protected String getRootId(String node_id) {
    754     return node_id;
    755     }
    756     /** returns a list of the child ids in order, null if no children
    757      * default implementation: return null */
    758     protected ArrayList getChildrenIds(String node_id) {
    759     return null;
    760     }
    761     /** returns the node id of the parent node, null if no parent
    762      * default implementation: return null */
    763     protected String getParentId(String node_id) {
    764     return null;
    765     }
    766 
    767     /** get the metadata for the doc node doc_id
    768      * returns a metadataList element:
    769      * <metadataList><metadata name="xxx">value</metadata></metadataList>
    770      */
    771     abstract protected Element getMetadataList(String doc_id,
    772                            boolean all_metadata,
    773                            ArrayList metadata_names) throws GSException;
    774     /** returns the content of a node
    775      * should return a nodeContent element:
    776      * <nodeContent>text content or other elements</nodeContent>
    777      * can return
    778      */
    779     abstract protected Element getNodeContent(String doc_id, String lang) throws GSException;
    780 
    781     /** returns the structural information asked for.
    782      * info_type may be one of
    783      * INFO_NUM_SIBS, INFO_NUM_CHILDREN, INFO_SIB_POS
    784      */
    785     abstract protected String getStructureInfo(String doc_id, String info_type);
    786 
    787     protected String getHrefOID(String href_url){
    788     return null;
    789     }
    790    
    791 }   
     745        {
     746            doc_type = getDocType(node_id);
     747        }
     748        node.setAttribute(GSXML.DOC_TYPE_ATT, doc_type);
     749        String node_type = getNodeType(node_id, doc_type);
     750        node.setAttribute(GSXML.NODE_TYPE_ATT, node_type);
     751        return node;
     752    }
     753
     754    /**
     755     * adds all the children of doc_id the the doc element, and if
     756     * recursive=true, adds all their children as well
     757     */
     758    protected void addDescendants(Element doc, String doc_id, boolean recursive)
     759    {
     760        ArrayList child_ids = getChildrenIds(doc_id);
     761        if (child_ids == null)
     762            return;
     763        for (int i = 0; i < child_ids.size(); i++)
     764        {
     765            String child_id = (String) child_ids.get(i);
     766            Element child_elem = createDocNode(child_id);
     767            doc.appendChild(child_elem);
     768            if (recursive && !child_elem.getAttribute(GSXML.NODE_TYPE_ATT).equals(GSXML.NODE_TYPE_LEAF))
     769            {
     770                addDescendants(child_elem, child_id, recursive);
     771            }
     772        }
     773    }
     774
     775    /**
     776     * adds all the siblings of current_id to the parent element. returns the
     777     * new current element
     778     */
     779    protected Element addSiblings(Element parent_node, String parent_id, String current_id)
     780    {
     781        Element current_node = GSXML.getFirstElementChild(parent_node);//(Element)parent_node.getFirstChild();
     782        if (current_node == null)
     783        {
     784            // create a sensible error message
     785            logger.error(" there should be a first child.");
     786            return null;
     787        }
     788        // remove the current child,- will add it in later in its correct place
     789        parent_node.removeChild(current_node);
     790
     791        // add in all the siblings,
     792        addDescendants(parent_node, parent_id, false);
     793
     794        // find the node that is now the current node
     795        // this assumes that the new node that was created is the same as
     796        // the old one that was removed - we may want to replace the new one
     797        // with the old one.
     798        Element new_current = GSXML.getNamedElement(parent_node, current_node.getNodeName(), GSXML.NODE_ID_ATT, current_id);
     799        return new_current;
     800    }
     801
     802    /**
     803     * returns true if oid ends in .fc (firstchild), .lc (lastchild), .pr
     804     * (parent), .ns (next sibling), .ps (prev sibling), .rt (root) .ss
     805     * (specified sibling), false otherwise
     806     */
     807    protected boolean idNeedsTranslating(String id)
     808    {
     809        return OID.needsTranslating(id);
     810    }
     811
     812    /** returns the list of sibling ids, including the specified node_id */
     813    protected ArrayList getSiblingIds(String node_id)
     814    {
     815        String parent_id = getParentId(node_id);
     816        if (parent_id == null)
     817        {
     818            return null;
     819        }
     820        return getChildrenIds(parent_id);
     821
     822    }
     823
     824    /**
     825     * returns the node type of the specified node. should be one of
     826     * GSXML.NODE_TYPE_LEAF, GSXML.NODE_TYPE_INTERNAL, GSXML.NODE_TYPE_ROOT
     827     */
     828    protected String getNodeType(String node_id, String doc_type)
     829    {
     830        if (doc_type.equals(GSXML.DOC_TYPE_SIMPLE))
     831        {
     832            return GSXML.NODE_TYPE_LEAF;
     833        }
     834
     835        if (getParentId(node_id) == null)
     836        {
     837            return GSXML.NODE_TYPE_ROOT;
     838        }
     839        if (doc_type.equals(GSXML.DOC_TYPE_PAGED))
     840        {
     841            return GSXML.NODE_TYPE_LEAF;
     842        }
     843        if (getChildrenIds(node_id) == null)
     844        {
     845            return GSXML.NODE_TYPE_LEAF;
     846        }
     847        return GSXML.NODE_TYPE_INTERNAL;
     848
     849    }
     850
     851    /**
     852     * if id ends in .fc, .pc etc, then translate it to the correct id default
     853     * implementation: just remove the suffix
     854     */
     855    protected String translateId(String id)
     856    {
     857        return id.substring(0, id.length());
     858    }
     859
     860    /**
     861     * if an id is not a greenstone id (an external id) then translate it to a
     862     * greenstone one default implementation: return the id
     863     */
     864    protected String translateExternalId(String id)
     865    {
     866        return id;
     867    }
     868
     869    /**
     870     * returns the document type of the doc that the specified node belongs to.
     871     * should be one of GSXML.DOC_TYPE_SIMPLE, GSXML.DOC_TYPE_PAGED,
     872     * GSXML.DOC_TYPE_HIERARCHY default implementation: return DOC_TYPE_SIMPLE
     873     */
     874    protected String getDocType(String node_id)
     875    {
     876        return GSXML.DOC_TYPE_SIMPLE;
     877    }
     878
     879    /**
     880     * returns the id of the root node of the document containing node node_id.
     881     * may be the same as node_id default implemntation: return node_id
     882     */
     883    protected String getRootId(String node_id)
     884    {
     885        return node_id;
     886    }
     887
     888    /**
     889     * returns a list of the child ids in order, null if no children default
     890     * implementation: return null
     891     */
     892    protected ArrayList getChildrenIds(String node_id)
     893    {
     894        return null;
     895    }
     896
     897    /**
     898     * returns the node id of the parent node, null if no parent default
     899     * implementation: return null
     900     */
     901    protected String getParentId(String node_id)
     902    {
     903        return null;
     904    }
     905
     906    /**
     907     * get the metadata for the doc node doc_id returns a metadataList element:
     908     * <metadataList><metadata name="xxx">value</metadata></metadataList>
     909     */
     910    abstract protected Element getMetadataList(String doc_id, boolean all_metadata, ArrayList metadata_names) throws GSException;
     911
     912    /**
     913     * returns the content of a node should return a nodeContent element:
     914     * <nodeContent>text content or other elements</nodeContent> can return
     915     */
     916    abstract protected Element getNodeContent(String doc_id, String lang) throws GSException;
     917
     918    /**
     919     * returns the structural information asked for. info_type may be one of
     920     * INFO_NUM_SIBS, INFO_NUM_CHILDREN, INFO_SIB_POS
     921     */
     922    abstract protected String getStructureInfo(String doc_id, String info_type);
     923
     924    protected String getHrefOID(String href_url)
     925    {
     926        return null;
     927    }
     928
     929}
Note: See TracChangeset for help on using the changeset viewer.