Changeset 25981

Show
Ignore:
Timestamp:
19.07.2012 14:32:42 (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/MapRetrieve.java

    r25635 r25981  
    22 
    33// Greenstone classes 
    4 import org.greenstone.gsdl3.util.*; 
    5  
    6 // XML classes 
    7 import org.w3c.dom.Document; 
    8 import org.w3c.dom.Element;  
     4import java.io.BufferedReader; 
     5import java.io.BufferedWriter; 
     6import java.io.File; 
     7import java.io.FileInputStream; 
     8import java.io.FileReader; 
     9import java.io.FileWriter; 
     10import java.io.IOException; 
     11import java.io.InputStreamReader; 
     12import java.io.ObjectInputStream; 
     13import java.util.ArrayList; 
     14import java.util.Arrays; 
     15import java.util.LinkedList; 
     16import java.util.Vector; 
     17 
     18import javax.swing.tree.DefaultMutableTreeNode; 
     19 
     20import org.apache.log4j.Logger; 
     21import org.greenstone.gsdl3.util.GSFile; 
     22import org.greenstone.gsdl3.util.GSPath; 
     23import org.greenstone.gsdl3.util.GSXML; 
     24import org.w3c.dom.Element; 
    925import org.w3c.dom.NodeList; 
    1026 
    11 // General Java classes 
    12 import java.io.*; 
    13 import java.util.StringTokenizer; 
    14 import java.util.Vector; 
    15 import java.util.Set; 
    16 import java.util.Iterator; 
    17 import java.lang.reflect.Array; 
    18 import java.util.Arrays; 
    19 import java.util.ArrayList; 
    20 import java.util.LinkedList; 
    21 import javax.swing.tree.DefaultMutableTreeNode; 
    22  
    23 import org.apache.log4j.*; 
    24  
    25 public class MapRetrieve 
    26     extends ServiceRack { 
    27  
    28     static Logger logger = Logger.getLogger(org.greenstone.gsdl3.service.MapRetrieve.class.getName()); 
    29  
    30     // the services on offer 
    31     protected static final String DOCUMENT_STRUCTURE_RETRIEVE_SERVICE = "DocumentStructureRetrieve"; 
    32     protected static final String DOCUMENT_METADATA_RETRIEVE_SERVICE = "DocumentMetadataRetrieve"; 
    33     protected static final String DOCUMENT_CONTENT_RETRIEVE_SERVICE = "DocumentContentRetrieve"; 
    34  
    35     protected static final int DOCUMENT=1; 
    36  
    37     protected ArrayList<String> index_name_list = null; 
    38     protected ArrayList<String> index_display_list = null; 
    39     protected String files_home_dir = null;  
    40     protected String temp_files_dir = null; 
    41     //protected String temp_image_file = null; 
    42     //protected String temp_image_file2 = null; 
    43     protected final String jpg_ext = ".jpg"; 
    44     protected String http_image_dir = null; 
    45     protected String http_temp_image_dir = null; 
    46     private LinkedList<String> namesInList = new LinkedList<String>(); 
    47  
    48     private DefaultMutableTreeNode tree; 
    49  
    50     /** constructor */ 
    51     public MapRetrieve() {} 
    52  
    53  
    54     /** configure this service */ 
    55     public boolean configure(Element info, Element extra_info) 
    56     { 
    57     if (!super.configure(info, extra_info)){ 
    58         return false; 
     27public class MapRetrieve extends ServiceRack 
     28{ 
     29 
     30    static Logger logger = Logger.getLogger(org.greenstone.gsdl3.service.MapRetrieve.class.getName()); 
     31 
     32    // the services on offer 
     33    protected static final String DOCUMENT_STRUCTURE_RETRIEVE_SERVICE = "DocumentStructureRetrieve"; 
     34    protected static final String DOCUMENT_METADATA_RETRIEVE_SERVICE = "DocumentMetadataRetrieve"; 
     35    protected static final String DOCUMENT_CONTENT_RETRIEVE_SERVICE = "DocumentContentRetrieve"; 
     36 
     37    protected static final int DOCUMENT = 1; 
     38 
     39    protected ArrayList<String> index_name_list = null; 
     40    protected ArrayList<String> index_display_list = null; 
     41    protected String files_home_dir = null; 
     42    protected String temp_files_dir = null; 
     43    //protected String temp_image_file = null; 
     44    //protected String temp_image_file2 = null; 
     45    protected final String jpg_ext = ".jpg"; 
     46    protected String http_image_dir = null; 
     47    protected String http_temp_image_dir = null; 
     48    private LinkedList<String> namesInList = new LinkedList<String>(); 
     49 
     50    private DefaultMutableTreeNode tree; 
     51 
     52    /** constructor */ 
     53    public MapRetrieve() 
     54    { 
    5955    } 
    6056 
    61     logger.info("Configuring MapRetrieve..."); 
    62     this.config_info = info; 
    63  
    64     // set up short_service_info_ - for now just has name and type 
    65     Element dmr_service = doc.createElement(GSXML.SERVICE_ELEM); 
    66     dmr_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE); 
    67     dmr_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_METADATA_RETRIEVE_SERVICE); 
    68     short_service_info.appendChild(dmr_service); 
    69  
    70     Element dcr_service = doc.createElement(GSXML.SERVICE_ELEM); 
    71     dcr_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE); 
    72     dcr_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_CONTENT_RETRIEVE_SERVICE); 
    73     short_service_info.appendChild(dcr_service); 
    74  
    75     Element dsr_service = doc.createElement(GSXML.SERVICE_ELEM); 
    76     dsr_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE); 
    77     dsr_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_STRUCTURE_RETRIEVE_SERVICE); 
    78     short_service_info.appendChild(dsr_service); 
    79  
    80     // set the files_home variable for this collection 
    81     this.files_home_dir = GSFile.collectionIndexDir(this.site_home, this.cluster_name)+ File.separator+"assoc"+File.separator;  
    82     this.temp_files_dir = GSFile.collectionBaseDir(this.site_home, this.cluster_name) + File.separator + "temp"+File.separator;  
    83  
    84         //this.files_home_dir + "maps" + File.separator + "temp" + File.separator; 
    85     //this.temp_image_file = this.temp_files_dir+"temp_"; 
    86     //this.temp_image_file2 = this.temp_files_dir+"temp2_"; 
    87      
    88      
    89     this.http_image_dir = this.site_http_address + "/collect/"+this.cluster_name+"/index/assoc/maps/"; 
    90     this.http_temp_image_dir = this.site_http_address + "/collect/"+this.cluster_name+"/temp/"; 
    91  
    92     this.index_name_list = new ArrayList<String>(); 
    93     this.index_display_list = new ArrayList<String>(); 
    94     Element index_list = (Element)GSXML.getChildByTagName(this.config_info, GSXML.INDEX_ELEM+GSXML.LIST_MODIFIER); 
    95     Element display_index_list = (Element)GSXML.getChildByTagName(extra_info, "search"); 
    96     if (index_list != null && display_index_list != null) { 
    97         NodeList indexes = index_list.getElementsByTagName(GSXML.INDEX_ELEM); 
    98         for (int i=0; i<indexes.getLength(); i++) { 
    99         String name = ((Element)indexes.item(i)).getAttribute(GSXML.NAME_ATT); 
    100         // add the index name 
    101         this.index_name_list.add(name); 
    102         // now look for the display name 
    103         Element this_index = GSXML.getNamedElement(display_index_list, "index", "name", name); 
    104         if (this_index != null) { 
    105             Element disp = GSXML.getNamedElement(this_index, "displayItem", "name", "name"); 
    106             if (disp != null) { 
    107             String display = GSXML.getNodeText(disp); 
    108             if (!display.equals("")) { 
    109                 this.index_display_list.add(display); 
    110                 continue; 
    111             } 
    112              
    113             } 
    114         } 
    115         // add the id as default text 
    116         this.index_display_list.add(name); 
    117  
    118         } 
     57    /** configure this service */ 
     58    public boolean configure(Element info, Element extra_info) 
     59    { 
     60        if (!super.configure(info, extra_info)) 
     61        { 
     62            return false; 
     63        } 
     64 
     65        logger.info("Configuring MapRetrieve..."); 
     66        this.config_info = info; 
     67 
     68        // set up short_service_info_ - for now just has name and type 
     69        Element dmr_service = doc.createElement(GSXML.SERVICE_ELEM); 
     70        dmr_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE); 
     71        dmr_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_METADATA_RETRIEVE_SERVICE); 
     72        short_service_info.appendChild(dmr_service); 
     73 
     74        Element dcr_service = doc.createElement(GSXML.SERVICE_ELEM); 
     75        dcr_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE); 
     76        dcr_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_CONTENT_RETRIEVE_SERVICE); 
     77        short_service_info.appendChild(dcr_service); 
     78 
     79        Element dsr_service = doc.createElement(GSXML.SERVICE_ELEM); 
     80        dsr_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE); 
     81        dsr_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_STRUCTURE_RETRIEVE_SERVICE); 
     82        short_service_info.appendChild(dsr_service); 
     83 
     84        // set the files_home variable for this collection 
     85        this.files_home_dir = GSFile.collectionIndexDir(this.site_home, this.cluster_name) + File.separator + "assoc" + File.separator; 
     86        this.temp_files_dir = GSFile.collectionBaseDir(this.site_home, this.cluster_name) + File.separator + "temp" + File.separator; 
     87 
     88        //this.files_home_dir + "maps" + File.separator + "temp" + File.separator; 
     89        //this.temp_image_file = this.temp_files_dir+"temp_"; 
     90        //this.temp_image_file2 = this.temp_files_dir+"temp2_"; 
     91 
     92        this.http_image_dir = this.site_http_address + "/collect/" + this.cluster_name + "/index/assoc/maps/"; 
     93        this.http_temp_image_dir = this.site_http_address + "/collect/" + this.cluster_name + "/temp/"; 
     94 
     95        this.index_name_list = new ArrayList<String>(); 
     96        this.index_display_list = new ArrayList<String>(); 
     97        Element index_list = (Element) GSXML.getChildByTagName(this.config_info, GSXML.INDEX_ELEM + GSXML.LIST_MODIFIER); 
     98        Element display_index_list = (Element) GSXML.getChildByTagName(extra_info, "search"); 
     99        if (index_list != null && display_index_list != null) 
     100        { 
     101            NodeList indexes = index_list.getElementsByTagName(GSXML.INDEX_ELEM); 
     102            for (int i = 0; i < indexes.getLength(); i++) 
     103            { 
     104                String name = ((Element) indexes.item(i)).getAttribute(GSXML.NAME_ATT); 
     105                // add the index name 
     106                this.index_name_list.add(name); 
     107                // now look for the display name 
     108                Element this_index = GSXML.getNamedElement(display_index_list, "index", "name", name); 
     109                if (this_index != null) 
     110                { 
     111                    Element disp = GSXML.getNamedElement(this_index, "displayItem", "name", "name"); 
     112                    if (disp != null) 
     113                    { 
     114                        String display = GSXML.getNodeText(disp); 
     115                        if (!display.equals("")) 
     116                        { 
     117                            this.index_display_list.add(display); 
     118                            continue; 
     119                        } 
     120 
     121                    } 
     122                } 
     123                // add the id as default text 
     124                this.index_display_list.add(name); 
     125 
     126            } 
     127        } 
     128 
     129        // look for document display format 
     130        String path = GSPath.appendLink(GSXML.DISPLAY_ELEM, GSXML.FORMAT_ELEM); 
     131        Element display_format = (Element) GSXML.getNodeByPath(extra_info, path); 
     132        if (display_format != null) 
     133        { 
     134            this.format_info_map.put(DOCUMENT_CONTENT_RETRIEVE_SERVICE, this.doc.importNode(display_format, true)); 
     135            // shoudl we make a copy? 
     136        } 
     137 
     138        // load the 2-dimensional tree for searching 
     139        try 
     140        { 
     141            ObjectInputStream objectin = new ObjectInputStream(new FileInputStream(this.files_home_dir + "nametree.dat")); 
     142            tree = (DefaultMutableTreeNode) objectin.readObject(); 
     143            objectin.close(); 
     144        } 
     145        catch (IOException ioe) 
     146        { 
     147            ioe.printStackTrace(); 
     148        } 
     149        catch (ClassNotFoundException cnfe) 
     150        { 
     151            cnfe.printStackTrace(); 
     152        } 
     153 
     154        return true; 
    119155    } 
    120156 
    121     // look for document display format 
    122     String path = GSPath.appendLink(GSXML.DISPLAY_ELEM, GSXML.FORMAT_ELEM); 
    123     Element display_format = (Element)GSXML.getNodeByPath(extra_info, path); 
    124     if (display_format != null) { 
    125         this.format_info_map.put(DOCUMENT_CONTENT_RETRIEVE_SERVICE, this.doc.importNode(display_format, true)); 
    126         // shoudl we make a copy? 
     157    /** */ 
     158    protected Element getServiceDescription(String service, String lang, String subset) 
     159    { 
     160        if (service.equals(DOCUMENT_STRUCTURE_RETRIEVE_SERVICE)) 
     161        { 
     162 
     163            Element tq_service = doc.createElement(GSXML.SERVICE_ELEM); 
     164            tq_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY); 
     165            tq_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_STRUCTURE_RETRIEVE_SERVICE); 
     166            return tq_service; 
     167        } 
     168        else if (service.equals(DOCUMENT_METADATA_RETRIEVE_SERVICE)) 
     169        { 
     170 
     171            Element tq_service = doc.createElement(GSXML.SERVICE_ELEM); 
     172            tq_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY); 
     173            tq_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_METADATA_RETRIEVE_SERVICE); 
     174            return tq_service; 
     175        } 
     176        else if (service.equals(DOCUMENT_CONTENT_RETRIEVE_SERVICE)) 
     177        { 
     178 
     179            Element tq_service = doc.createElement(GSXML.SERVICE_ELEM); 
     180            tq_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY); 
     181            tq_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_CONTENT_RETRIEVE_SERVICE); 
     182            return tq_service; 
     183        } 
     184 
     185        return null; 
     186 
    127187    } 
    128188 
    129     // load the 2-dimensional tree for searching 
    130     try{ 
    131         ObjectInputStream objectin = new ObjectInputStream(new FileInputStream(this.files_home_dir+"nametree.dat")); 
    132         tree = (DefaultMutableTreeNode)objectin.readObject(); 
    133         objectin.close(); 
    134     }catch(IOException ioe){ 
    135         ioe.printStackTrace(); 
    136     }catch(ClassNotFoundException cnfe){ 
    137         cnfe.printStackTrace(); 
     189    /** Retrieve the structure of a document */ 
     190    protected Element processDocumentStructureRetrieve(Element request) 
     191    { 
     192        // Create a new (empty) result message 
     193        Element result = doc.createElement(GSXML.RESPONSE_ELEM); 
     194        return result; 
    138195    } 
    139      
    140  
    141     return true; 
    142     } 
    143  
    144     /** */ 
    145     protected Element getServiceDescription(String service, String lang, String subset)  
    146     { 
    147     if (service.equals(DOCUMENT_STRUCTURE_RETRIEVE_SERVICE)) { 
    148          
    149         Element tq_service = doc.createElement(GSXML.SERVICE_ELEM); 
    150         tq_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY); 
    151         tq_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_STRUCTURE_RETRIEVE_SERVICE); 
    152         return tq_service; 
     196 
     197    protected Element processDocumentMetadataRetrieve(Element request) 
     198    { 
     199        // Create a new (empty) result message 
     200        try 
     201        { 
     202            Element result = this.doc.createElement(GSXML.RESPONSE_ELEM); 
     203 
     204            String uid = request.getAttribute(GSXML.USER_ID_ATT); 
     205            if (uid.equals("")) 
     206            { 
     207                logger.info("in metadata retrieve, uid = ''\n" + converter.getPrettyString(request)); 
     208            } 
     209            result.setAttribute(GSXML.FROM_ATT, DOCUMENT_METADATA_RETRIEVE_SERVICE); 
     210            result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS); 
     211 
     212            // Get the parameters of the request 
     213            Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER); 
     214            if (param_list == null) 
     215            { 
     216                logger.error("missing paramList.\n"); 
     217                return result; // Return the empty result 
     218            } 
     219 
     220            // The metadata information required 
     221            Vector<String> metadata_list = new Vector<String>(); 
     222            boolean all_metadata = false; 
     223            // Process the request parameters 
     224            Element param = GSXML.getFirstElementChild(param_list);//(Element) param_list.getFirstChild(); 
     225 
     226            while (param != null) 
     227            { 
     228                // Identify the metadata information desired 
     229                if (param.getAttribute(GSXML.NAME_ATT).equals("metadata")) 
     230                { 
     231                    String metadata = GSXML.getValue(param); 
     232                    if (metadata.equals("all")) 
     233                    { 
     234                        all_metadata = true; 
     235                        break; 
     236                    } 
     237                    metadata_list.add(metadata); 
     238                } 
     239                param = (Element) param.getNextSibling(); 
     240            } 
     241 
     242            Element node_list = this.doc.createElement(GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER); 
     243            result.appendChild(node_list); 
     244 
     245            // Get the documents 
     246            Element request_node_list = (Element) GSXML.getChildByTagName(request, GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER); 
     247            if (request_node_list == null) 
     248            { 
     249                logger.error(" DocumentMetadataRetrieve request had no " + GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER); 
     250                return result; 
     251            } 
     252 
     253            NodeList request_nodes = request_node_list.getChildNodes(); 
     254 
     255            try 
     256            { 
     257                //used just to ensure outfile is initialised 
     258                BufferedWriter outfile = new BufferedWriter(new FileWriter(this.temp_files_dir + "emptynothingness")); 
     259 
     260                for (int i = 0; i < request_nodes.getLength(); i++) 
     261                { 
     262                    Element request_node = (Element) request_nodes.item(i); 
     263                    String node_id = request_node.getAttribute(GSXML.NODE_ID_ATT); 
     264                    String place_data = ""; 
     265                    String year = ""; 
     266                    String coOrdinates = ""; 
     267                    String thumb = ""; 
     268                    String link = ""; 
     269                    int mapFreq = 0; 
     270                    LinkedList place_data_list = new LinkedList(); 
     271                    LinkedList coOrdinates_list = new LinkedList(); 
     272 
     273                    //if this is a first displaying of the map 
     274                    if (node_id.indexOf("```") != -1 && node_id.indexOf("imageChooser") == -1) 
     275                    { 
     276                        //get the number of query terms on this map 
     277                        mapFreq = Integer.parseInt(node_id.substring(node_id.lastIndexOf('`', node_id.indexOf("```") - 1) + 1, node_id.indexOf("```"))); 
     278                        //get the place names on this map 
     279                        place_data = node_id.substring(node_id.indexOf("```") + 3, node_id.length()); 
     280                        //get the map metadata 
     281                        node_id = node_id.substring(0, node_id.indexOf('`', node_id.indexOf("```"))); 
     282 
     283                        try 
     284                        { 
     285                            // loop for each query term on the map 
     286                            for (int r = 0; r < mapFreq; r++) 
     287                            { 
     288                                // get title, type, location, and the string for creating the hyperlink for this query term 
     289                                String title = place_data.substring(0, place_data.indexOf('`')); 
     290                                String type = place_data.substring(place_data.indexOf('`') + 1, place_data.indexOf('`', place_data.indexOf('`') + 1)); 
     291                                String location = place_data.substring(place_data.indexOf('`', place_data.indexOf('`') + 1) + 1, place_data.indexOf('`', place_data.indexOf('`', place_data.indexOf('`') + 1) + 1)); 
     292                                if (place_data.indexOf("```") != -1) 
     293                                    link = place_data.substring(0, place_data.indexOf("```")); 
     294                                else 
     295                                    link = place_data; 
     296                                // resolve the type and location 
     297                                type = getType(type); 
     298                                location = getLocation(location); 
     299                                // remove this query term from the string 
     300                                if (place_data.indexOf("```") != -1) 
     301                                    place_data = place_data.substring(place_data.indexOf("```") + 3, place_data.length()); 
     302 
     303                                //add the co-ordinates of this query term to the co-ordinates list 
     304                                coOrdinates_list.add("`" + link.substring(link.lastIndexOf('`') + 1, link.length()) + "`" + link.substring(link.lastIndexOf('`', link.lastIndexOf('`') - 1) + 2, link.lastIndexOf('`'))); 
     305 
     306                                // add the title, type and location to the places list 
     307                                place_data_list.add(title + ", " + type + ", " + location + ";"); 
     308                            } 
     309                        } 
     310                        catch (StringIndexOutOfBoundsException sioobe) 
     311                        { 
     312                            sioobe.printStackTrace(); 
     313                        } 
     314                    } 
     315 
     316                    // Add the document to the list 
     317                    Element new_node = (Element) this.doc.importNode(request_node, false); 
     318                    node_list.appendChild(new_node); 
     319 
     320                    // Add the requested metadata information 
     321                    Element node_meta_list = this.doc.createElement(GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER); 
     322                    new_node.appendChild(node_meta_list); 
     323 
     324                    // create the navigation thumbnails.  This doesn't seem to work most of the time ??????? 
     325                    for (int m = 0; m < metadata_list.size(); m++) 
     326                    { 
     327                        String metadata = metadata_list.get(m); 
     328                        thumb = ""; 
     329                        String value = ""; 
     330                        if (node_id.indexOf('.') != -1) 
     331                            thumb = node_id.substring(0, node_id.indexOf('.')); 
     332                        if (node_id.indexOf('`') != -1) 
     333                            value = node_id.substring(node_id.lastIndexOf('`', node_id.lastIndexOf('`') - 1) + 1, node_id.lastIndexOf('`', node_id.lastIndexOf('`') - 1) + 5); 
     334                        year = value; 
     335 
     336                        place_data = ""; 
     337                        if (place_data_list.size() != 0) 
     338                            for (int q = 0; q < mapFreq; q++) 
     339                            { 
     340                                link = (String) place_data_list.get(q); 
     341                                if (q != 0) 
     342                                { 
     343                                    place_data = place_data + "<br>" + link; 
     344                                } 
     345                                else 
     346                                { 
     347                                    place_data = link; 
     348                                    coOrdinates = "``"; 
     349                                } 
     350                                coOrdinates = coOrdinates + (String) coOrdinates_list.get(q); 
     351                            } 
     352 
     353                        link = "<a href=\"?a=d&c=" + this.cluster_name + "&d=" + node_id + coOrdinates + "&dt=map\">"; 
     354                        thumb = "<img src=\"" + this.http_image_dir + thumb + "thumb.jpg\" border=0>"; 
     355                        value = "<table><tr><td>" + link + "<p>" + place_data + "<br>" + value + "</a></td><td>" + link + thumb + "</a></td></tr></table>"; 
     356                        if (metadata.equals("Title")) 
     357                            if (!(place_data.equals("")) && place_data.indexOf(", , ;") == -1 && node_id.indexOf("```") == -1) 
     358                                GSXML.addMetadata(this.doc, node_meta_list, "Title", value);//metadata, value); 
     359                            else 
     360                                GSXML.addMetadata(this.doc, node_meta_list, metadata, ""); 
     361 
     362                        if (place_data.indexOf(", , ;") == -1) 
     363                        { 
     364                            if (i == 0) 
     365                                if (!(mapFreq == 0)) 
     366                                { 
     367                                    outfile = new BufferedWriter(new FileWriter(this.temp_files_dir + "links" + uid)); 
     368                                    outfile.write("<table align=\"center\"><tr>"); 
     369                                } 
     370 
     371                            if (!(mapFreq == 0)) 
     372                            { 
     373                                if (i % 7 == 0) 
     374                                    outfile.write("</tr><tr>"); 
     375                                outfile.write("<td align=\"center\">" + link + thumb + "</a><br>" + link + year + "</a></td>"); 
     376                            } 
     377 
     378                            if (i == request_nodes.getLength() - 1) 
     379                            { 
     380                                outfile.write("</tr></table><p>"); 
     381                                outfile.flush(); 
     382                                outfile.close(); 
     383                            } 
     384                        } 
     385                    } 
     386 
     387                } 
     388            } 
     389            catch (IOException ioe) 
     390            { 
     391                ioe.printStackTrace(); 
     392            } 
     393 
     394            return result; 
     395        } 
     396        catch (Exception excep) 
     397        { 
     398            excep.printStackTrace(); 
     399        } 
     400        return null; 
     401 
    153402    } 
    154     else if (service.equals(DOCUMENT_METADATA_RETRIEVE_SERVICE)) { 
    155          
    156         Element tq_service = doc.createElement(GSXML.SERVICE_ELEM); 
    157         tq_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY); 
    158         tq_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_METADATA_RETRIEVE_SERVICE); 
    159         return tq_service; 
     403 
     404    protected Element processDocumentContentRetrieve(Element request) 
     405    { 
     406        // Create a new (empty) result message 
     407        Element result = doc.createElement(GSXML.RESPONSE_ELEM); 
     408        result.setAttribute(GSXML.FROM_ATT, DOCUMENT_CONTENT_RETRIEVE_SERVICE); 
     409        result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS); 
     410 
     411        String uid = request.getAttribute(GSXML.USER_ID_ATT); 
     412        String temp_image_file = this.temp_files_dir + "temp_" + uid + ".jpg"; 
     413        String temp_image_file2 = this.temp_files_dir + "temp_" + uid + "_2.jpg"; 
     414 
     415        Element query_doc_list = (Element) GSXML.getChildByTagName(request, GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER); 
     416        if (query_doc_list == null) 
     417        { 
     418            logger.error("DocumentContentRetrieve request specified no doc nodes.\n"); 
     419            return result; 
     420        } 
     421 
     422        String legend_file = this.temp_files_dir + "legend_" + uid + ".jpg"; 
     423        String blank_file = this.files_home_dir + "blank.jpg"; 
     424        Element doc_list = doc.createElement(GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER); 
     425        result.appendChild(doc_list); 
     426 
     427        // Get the documents 
     428        String[] doc_ids = GSXML.getAttributeValuesFromList(query_doc_list, GSXML.NODE_ID_ATT); 
     429 
     430        for (int i = 0; i < doc_ids.length; i++) 
     431        { 
     432            String doc_id = doc_ids[i]; 
     433            // img_num is the name of the map file eg. 072.jpg 
     434            String img_num = doc_id.substring(0, doc_id.indexOf('.')); 
     435            // strings for inserting image in html 
     436            String img_left = "<img border=0 src=\"" + this.http_temp_image_dir; 
     437            String doc_content = ""; 
     438            String co_ordinates = ""; 
     439            String img_size = ""; 
     440            int height = 0; 
     441            int width = 0; 
     442            // the number for the legend image if adding locations to the map 
     443            int leg_num = 0; 
     444            double ratio = 0; 
     445 
     446            // if user has clicked on the map.  This does not resolve maps that are not North oriented. 
     447            if (doc_id.indexOf("imageChooser") == 0) 
     448            { 
     449                try 
     450                { 
     451                    doc_id = doc_id.substring(doc_id.indexOf('`') + 1, doc_id.length()); 
     452                    img_num = doc_id.substring(0, doc_id.indexOf('.')); 
     453 
     454                    // get the map size 
     455                    String get_size[] = { "identify", "-size", "10000", temp_image_file }; 
     456                    Process proc; 
     457                    proc = Runtime.getRuntime().exec(get_size); 
     458                    BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream())); 
     459                    img_size = br.readLine(); 
     460                    proc.waitFor(); 
     461                    img_size = img_size.substring(img_size.indexOf("JPEG") + 5, img_size.indexOf(" ", img_size.indexOf("JPEG") + 5)); 
     462                    width = Integer.parseInt(img_size.substring(0, img_size.indexOf("x"))); 
     463                    height = Integer.parseInt(img_size.substring(img_size.indexOf("x") + 1, img_size.length())); 
     464 
     465                    // scale image size according to the ratio 
     466                    ratio = Double.parseDouble(doc_id.substring(doc_id.lastIndexOf('`', doc_id.indexOf("```") - 1) + 1, doc_id.indexOf("```"))); 
     467                    width = (int) (width * ratio); 
     468                    height = (int) (height * ratio); 
     469 
     470                    // get the position of the mouse click on the image 
     471                    int xclick = Integer.parseInt(doc_id.substring(doc_id.indexOf("```") + 3, doc_id.lastIndexOf('`'))); 
     472                    int yclick = Integer.parseInt(doc_id.substring(doc_id.lastIndexOf('`') + 1, doc_id.length())); 
     473                    doc_id = doc_id.substring(doc_id.indexOf('`') + 1, doc_id.indexOf("```")); 
     474 
     475                    // convert click position to percentage distance accross and down the image. 
     476                    double xpercent = (xclick * 1.0) / width; 
     477                    double ypercent = (yclick * 1.0) / height; 
     478 
     479                    // get the top left and bottom right co-ordinates of the map 
     480                    double ytop = Double.parseDouble(doc_id.substring(0, doc_id.indexOf('`'))) * -1; 
     481                    doc_id = doc_id.substring(doc_id.indexOf('`') + 1, doc_id.length()); 
     482                    double xleft = Double.parseDouble(doc_id.substring(0, doc_id.indexOf('`'))); 
     483                    doc_id = doc_id.substring(doc_id.indexOf('`') + 1, doc_id.length()); 
     484                    double ybot = Double.parseDouble(doc_id.substring(0, doc_id.indexOf('`'))) * -1; 
     485                    doc_id = doc_id.substring(doc_id.indexOf('`') + 1, doc_id.length()); 
     486                    double xright = Double.parseDouble(doc_id.substring(0, doc_id.indexOf('`'))); 
     487                    doc_id = doc_id.substring(doc_id.indexOf('`') + 1, doc_id.length()); 
     488 
     489                    // calculate the map co-ordinates of the mouse click 
     490                    xpercent = ((xright - xleft) * xpercent) + xleft; 
     491                    ypercent = ((ybot - ytop) * ypercent) + ytop; 
     492 
     493                    // search the tree for nearby place names 
     494                    namesInList.clear(); 
     495                    findName(xpercent, ypercent, 0.1, 0.1, tree, true); 
     496 
     497                    int namesInArraySize = namesInList.size(); 
     498                    String returnNames[] = new String[namesInArraySize]; 
     499 
     500                    //put the names in an array 
     501                    for (int ri = 0; namesInList.size() > 0; ri++) 
     502                    { 
     503                        returnNames[ri] = namesInList.getFirst(); 
     504                        returnNames[ri] = returnNames[ri].substring(0, returnNames[ri].indexOf('`')); 
     505                        namesInList.removeFirst(); 
     506                    } 
     507 
     508                    //sort the names 
     509                    Arrays.sort(returnNames); 
     510                    doc_content = "\n<script>\nfunction openIt(loc){\n\topener.location=loc;\n\tself.close();\n}\n</script>"; 
     511                    for (int nameIndex = 0; nameIndex < namesInArraySize; nameIndex++) 
     512                    { 
     513                        String tempName = returnNames[nameIndex]; 
     514                        //convert names with spaces for hyperlinks 
     515                        if (returnNames[nameIndex].indexOf(' ') != -1) 
     516                        { 
     517                            returnNames[nameIndex] = returnNames[nameIndex].replaceAll(" ", "+"); 
     518                            returnNames[nameIndex] = "%22" + returnNames[nameIndex] + "%22"; 
     519                        } 
     520                        // add the place name to the html 
     521                        doc_content = doc_content + "<a href=\"\" onClick=openIt('?a=q&sa=&rt=r&s=MapQuery&c=" + this.cluster_name + "&startPage=1&s1.index=none&s1.maxDocs=10&s1.query=" + returnNames[nameIndex] + "')>" + tempName + "</a><br>"; 
     522                    } 
     523 
     524                } 
     525                catch (Exception ioexception) 
     526                { 
     527                    ioexception.printStackTrace(); 
     528                } 
     529            } 
     530            else 
     531            { 
     532 
     533                try 
     534                { 
     535                    //file for converting image     
     536                    BufferedWriter bw = new BufferedWriter(new FileWriter(this.temp_files_dir + "add_x_" + uid)); 
     537                    ; 
     538                    Process proc; 
     539 
     540                    // if a new search 
     541                    if (doc_id.indexOf("```") != -1) 
     542                    { 
     543                        // copy requested map to temp.jpg 
     544                        proc = Runtime.getRuntime().exec("cp " + this.files_home_dir + "maps" + File.separator + img_num + ".jpg " + temp_image_file); 
     545                        proc.waitFor(); 
     546                    } 
     547 
     548                    //get the image size 
     549                    String get_size[] = { "identify", "-size", "10000", temp_image_file }; 
     550                    proc = Runtime.getRuntime().exec(get_size); 
     551                    BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream())); 
     552                    img_size = br.readLine(); 
     553                    proc.waitFor(); 
     554                    img_size = img_size.substring(img_size.indexOf("JPEG") + 5, img_size.indexOf(" ", img_size.indexOf("JPEG") + 5)); 
     555                    if (img_size.indexOf("+") != -1) 
     556                    { 
     557                        img_size = img_size.substring(0, img_size.indexOf("+")); 
     558                    } 
     559                    width = Integer.parseInt(img_size.substring(0, img_size.indexOf("x"))); 
     560                    height = Integer.parseInt(img_size.substring(img_size.indexOf("x") + 1, img_size.length())); 
     561 
     562                    // if a new search 
     563                    if (doc_id.indexOf("```") != -1) 
     564                    { 
     565                        co_ordinates = doc_id.substring(doc_id.indexOf("```") + 2, doc_id.length()); 
     566                        // get the number of places to mark on the map 
     567                        int x_number = Integer.parseInt(doc_id.substring(doc_id.lastIndexOf('`', doc_id.indexOf("```") - 1) + 1, doc_id.indexOf("```"))); 
     568 
     569                        //write the convert command 
     570                        bw.write("convert -font helvetica -fill red -pointsize 48 "); 
     571 
     572                        for (int xi = 0; xi < x_number; xi++) 
     573                        { 
     574 
     575                            // get the co-ordinates of the place name 
     576                            double xco = Double.parseDouble(co_ordinates.substring(co_ordinates.lastIndexOf('`', co_ordinates.lastIndexOf('`') - 1) + 1, co_ordinates.lastIndexOf('`', co_ordinates.lastIndexOf('`') - 1) + 7)); 
     577                            double yco = Double.parseDouble(co_ordinates.substring(co_ordinates.lastIndexOf('`') + 1, co_ordinates.length())); 
     578                            if (xi != x_number - 1) 
     579                                co_ordinates = co_ordinates.substring(0, co_ordinates.lastIndexOf('`', co_ordinates.lastIndexOf('`') - 1)); 
     580 
     581                            int index = 0; 
     582                            index = doc_id.indexOf('`') + 2; 
     583 
     584                            // get the zoom ratio and the top left and bottom right co-ordinates of the map 
     585                            ratio = 0.4; 
     586                            double tly = Double.parseDouble(doc_id.substring(index, index + 5)); 
     587                            index = doc_id.indexOf('`', index) + 1; 
     588                            double tlx = Double.parseDouble(doc_id.substring(index, index + 6)); 
     589                            index = doc_id.indexOf('`', index) + 2; 
     590                            double bry = Double.parseDouble(doc_id.substring(index, index + 5)); 
     591                            index = doc_id.indexOf('`', index) + 1; 
     592                            double brx = Double.parseDouble(doc_id.substring(index, index + 6)); 
     593                            index = doc_id.indexOf('`', index) + 1; 
     594                            double orient = Double.parseDouble(doc_id.substring(index, doc_id.indexOf('`', index))); 
     595 
     596                            // find the centre of the map 
     597                            double xcent = ((brx - tlx) / 2) + tlx; 
     598                            double ycent = ((bry - tly) / 2) + tly; 
     599 
     600                            // get the orientation of the map 
     601                            orient = Math.toRadians(orient); 
     602 
     603                            // rotate the co-ordinates around the centre of the map  
     604                            xco = xco - xcent; 
     605                            yco = yco - ycent; 
     606                            double oldx = xco; 
     607                            xco = xco * Math.cos(orient) - yco * Math.sin(orient); 
     608                            yco = oldx * Math.sin(orient) + yco * Math.cos(orient); 
     609                            xco = xco + xcent; 
     610                            yco = yco + ycent; 
     611                            xco = (xco - tlx) / (brx - tlx); 
     612                            yco = (yco - tly) / (bry - tly); 
     613 
     614                            // calculate the pixels for placing the mark 
     615                            width = (int) (xco * width) - 5; 
     616                            height = (int) (yco * height) - 5; 
     617 
     618                            // write the options for convert 
     619                            bw.write("-draw 'text " + width + "," + height + " \"x\"' "); 
     620                            bw.flush(); 
     621 
     622                            // reset the width and height variables for the image 
     623                            width = Integer.parseInt(img_size.substring(0, img_size.indexOf("x"))); 
     624                            height = Integer.parseInt(img_size.substring(img_size.indexOf("x") + 1, img_size.length())); 
     625                        } 
     626                        doc_id = doc_id.substring(0, doc_id.lastIndexOf('`', doc_id.indexOf("```") - 1)); 
     627 
     628                        // write the end of the convert command, then command for zooming image to the right level, then command to copy the blank image over legend.jpg 
     629                        bw.write(temp_image_file + " " + temp_image_file + ";convert -scale " + ((int) (ratio * width)) + "x" + ((int) (ratio * height)) + " " + temp_image_file + " " + temp_image_file2 + ";cp " + blank_file + " " + legend_file); 
     630 
     631                        // reset legend number 
     632                        leg_num = 0; 
     633                    } 
     634 
     635                    else 
     636                    // if changing zoom level 
     637                    if (doc_id.substring(doc_id.lastIndexOf('`'), doc_id.length()).indexOf('.') != -1) 
     638                    { 
     639                        // get the ratio 
     640                        ratio = Double.parseDouble(doc_id.substring(doc_id.lastIndexOf('`') + 1, doc_id.length())); 
     641                        // write the command for scaling image 
     642                        bw.write("convert -scale " + ((int) (ratio * width)) + "x" + ((int) (ratio * height)) + " " + temp_image_file + " " + temp_image_file2); 
     643                        doc_id = doc_id.substring(0, doc_id.lastIndexOf('`')); 
     644                    } 
     645 
     646                    // if adding locations to map 
     647                    else 
     648                    { 
     649 
     650                        // get the location type to add 
     651                        String restricter = doc_id.substring(doc_id.lastIndexOf('`') + 1, doc_id.length()); 
     652                        doc_id = doc_id.substring(0, doc_id.lastIndexOf('`')); 
     653 
     654                        // get the number for the legend image 
     655                        leg_num = Integer.parseInt(doc_id.substring(doc_id.lastIndexOf('`') + 1, doc_id.length())); 
     656                        doc_id = doc_id.substring(0, doc_id.lastIndexOf('`')); 
     657 
     658                        //open file for location type 
     659                        BufferedReader inType = new BufferedReader(new FileReader(this.files_home_dir + "place_types" + File.separator + restricter + ".txt")); 
     660 
     661                        //check through the file and add any places that are in the bounds of this map. 
     662 
     663                        // check value. set to true if a place to add is found 
     664                        boolean add_place_type = false; 
     665 
     666                        int index = 0; 
     667                        index = doc_id.indexOf('`') + 2; 
     668                        // get zoom ratio 
     669                        ratio = Double.parseDouble(doc_id.substring(doc_id.lastIndexOf('`') + 1, doc_id.length())); 
     670                        // get top left and bottom right co-ordinates of the map 
     671                        double tly = Double.parseDouble(doc_id.substring(index, index + 5)); 
     672                        index = doc_id.indexOf('`', index) + 1; 
     673                        double tlx = Double.parseDouble(doc_id.substring(index, index + 6)); 
     674                        index = doc_id.indexOf('`', index) + 2; 
     675                        double bry = Double.parseDouble(doc_id.substring(index, index + 5)); 
     676                        index = doc_id.indexOf('`', index) + 1; 
     677                        double brx = Double.parseDouble(doc_id.substring(index, index + 6)); 
     678                        index = doc_id.indexOf('`', index) + 1; 
     679                        // get orientation of the map 
     680                        double orient = Double.parseDouble(doc_id.substring(index, doc_id.indexOf('`', index))); 
     681                        // calculate centre of map 
     682                        double xcent = ((brx - tlx) / 2) + tlx; 
     683                        double ycent = ((bry - tly) / 2) + tly; 
     684                        orient = Math.toRadians(orient); 
     685 
     686                        String type_point = ""; 
     687                        double xco = 0.0; 
     688                        double yco = 0.0; 
     689 
     690                        // read the file 
     691                        while (inType.ready()) 
     692                        { 
     693                            //read a line 
     694                            type_point = inType.readLine(); 
     695 
     696                            // get the co-ordinates of the point 
     697                            xco = Double.parseDouble(type_point.substring(type_point.lastIndexOf('`') + 1, type_point.length())); 
     698                            yco = Double.parseDouble(type_point.substring(type_point.lastIndexOf('`', type_point.lastIndexOf('`') - 1) + 2, type_point.lastIndexOf('`'))); 
     699 
     700                            // if it is within the co-ordinates of the map 
     701                            if (xco >= tlx && xco < brx && yco >= tly && yco < bry) 
     702                            { 
     703                                // rotate the point around the centre according to map orientation 
     704                                xco = xco - xcent; 
     705                                yco = yco - ycent; 
     706                                double oldx = xco; 
     707                                xco = xco * Math.cos(orient) - yco * Math.sin(orient); 
     708                                yco = oldx * Math.sin(orient) + yco * Math.cos(orient); 
     709                                xco = xco + xcent; 
     710                                yco = yco + ycent; 
     711                                // get the pixels for where to place the mark 
     712                                xco = (xco - tlx) / (brx - tlx); 
     713                                yco = (yco - tly) / (bry - tly); 
     714                                width = (int) (xco * width) - 5; 
     715                                height = (int) (yco * height) - 5; 
     716 
     717                                //if this is the first point to be added 
     718                                if (!add_place_type) 
     719                                { 
     720                                    // write the initial convert command 
     721                                    bw.write("convert -font helvetica -fill red -pointsize 36 "); 
     722                                    // toggle check value 
     723                                    add_place_type = true; 
     724                                } 
     725 
     726                                // write the options for the convert command 
     727                                bw.write("-draw 'text " + width + "," + height + " \"" + leg_num + "\"' "); 
     728                                bw.flush(); 
     729 
     730                                // reset width and height variables for the image 
     731                                width = Integer.parseInt(img_size.substring(0, img_size.indexOf("x"))); 
     732                                height = Integer.parseInt(img_size.substring(img_size.indexOf("x") + 1, img_size.length())); 
     733                            } 
     734                        } 
     735 
     736                        //if there are places to mark on the map 
     737                        if (add_place_type) 
     738                        { 
     739                            // finish the convert command and write command for scaling image 
     740                            bw.write(temp_image_file + " " + temp_image_file + ";convert -scale " + ((int) (ratio * width)) + "x" + ((int) (ratio * height)) + " " + temp_image_file + " " + temp_image_file2); 
     741 
     742                            // open file for converting the legend command 
     743                            BufferedWriter buf = new BufferedWriter(new FileWriter(this.temp_files_dir + "add_l_" + uid)); 
     744                            if (leg_num == 1) 
     745                                buf.write("cp " + blank_file + " " + legend_file + ";"); 
     746                            // write the command for adding to the legend 
     747                            buf.write("convert -font helvetica -fill red -pointsize 12 -draw 'text 15," + (leg_num * 15 + 20) + " \"" + leg_num + " " + getType(restricter) + "\"' " + legend_file + " " + legend_file); 
     748                            buf.flush(); 
     749                            buf.close(); 
     750                            // execute the command for the legend image 
     751                            proc = Runtime.getRuntime().exec("sh " + this.temp_files_dir + "add_l_" + uid); 
     752                            proc.waitFor(); 
     753                        } 
     754                        inType.close(); 
     755                    } 
     756                    bw.flush(); 
     757                    bw.close(); 
     758 
     759                    // execute the convert commands etc. 
     760                    proc = Runtime.getRuntime().exec("sh " + this.temp_files_dir + "add_x_" + uid); 
     761                    proc.waitFor(); 
     762 
     763                } 
     764                catch (Exception ioe) 
     765                { 
     766                    ioe.printStackTrace(); 
     767                } 
     768 
     769                //write the html for the document 
     770 
     771                String doc_content_head = "?a=d&c=" + this.cluster_name + "&dt=map&d="; 
     772                doc_content = "<td valign=\"top\"><script>document.write('" + img_left + "legend_" + uid + ".jpg" + "?'+new Date().getTime())</script>\"></td>"; 
     773                doc_content = doc_content + "<td><script>document.write('" + img_left + "temp_" + uid + "_2.jpg?'+new Date().getTime())</script>\" onclick=\"imgClickHandler(event, this, '" + img_num + "')\"></td>"; 
     774 
     775                // replace _httpimg_ with the correct address 
     776                doc_content = "<table><tr>" + doc_content + "</tr></table>"; 
     777 
     778                String javascript = getJavascript(ratio, doc_id, leg_num); 
     779 
     780                doc_content = "<center>You are currently viewing the map at " + (int) (ratio * 100) + "%<br>Select a radio button for a new zoom level.</center>" + javascript + doc_content; 
     781                doc_content = doc_content.replaceAll("zoomhead", doc_content_head); 
     782                doc_content = doc_content.replaceAll("placeChooserImage", doc_content_head + "imageChooser`" + doc_id + "`" + ratio); 
     783 
     784                // read the file for the navigation thumbnails 
     785                try 
     786                { 
     787                    BufferedReader infile = new BufferedReader(new FileReader(this.temp_files_dir + "links" + uid)); 
     788                    doc_content = doc_content + infile.readLine(); 
     789                    infile.close(); 
     790                } 
     791                catch (Exception ioexc) 
     792                { 
     793                    ioexc.printStackTrace(); 
     794                } 
     795            } 
     796 
     797            // put the html in a text node 
     798            Element text_doc = doc.createElement(GSXML.DOC_NODE_ELEM); 
     799            text_doc.setAttribute(GSXML.NODE_ID_ATT, doc_id); 
     800            GSXML.addDocText(doc, text_doc, doc_content); 
     801            doc_list.appendChild(text_doc); 
     802 
     803        } 
     804        return result; 
    160805    } 
    161     else if (service.equals(DOCUMENT_CONTENT_RETRIEVE_SERVICE)) { 
    162          
    163         Element tq_service = doc.createElement(GSXML.SERVICE_ELEM); 
    164         tq_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY); 
    165         tq_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_CONTENT_RETRIEVE_SERVICE); 
    166         return tq_service; 
     806 
     807    // resolves location codes for places from LINZ database 
     808    private String getLocation(String location) 
     809    { 
     810        String read; 
     811        try 
     812        { 
     813            BufferedReader in = new BufferedReader(new FileReader(this.files_home_dir + "files" + File.separator + "landdist.txt")); 
     814            in.readLine(); 
     815            while (in.ready()) 
     816            { 
     817                read = in.readLine(); 
     818                if (read.substring(0, 2).equals(location)) 
     819                { 
     820                    in.close(); 
     821                    return read.substring(3, read.length()); 
     822                } 
     823            } 
     824        } 
     825        catch (Exception e) 
     826        { 
     827        } 
     828        return ""; 
    167829    } 
    168830 
    169     return null; 
    170      
    171     } 
    172  
    173     /** Retrieve the structure of a document */ 
    174     protected Element processDocumentStructureRetrieve(Element request) 
    175     { 
    176     // Create a new (empty) result message 
    177     Element result = doc.createElement(GSXML.RESPONSE_ELEM); 
    178     return result; 
    179     } 
    180  
    181     protected Element processDocumentMetadataRetrieve(Element request) { 
    182     // Create a new (empty) result message 
    183     try{ 
    184     Element result = this.doc.createElement(GSXML.RESPONSE_ELEM); 
    185  
    186     String uid = request.getAttribute(GSXML.USER_ID_ATT); 
    187     if (uid.equals("")) { 
    188         logger.info("in metadata retrieve, uid = ''\n"+converter.getPrettyString(request)); 
     831    // resolves type codes for the LINZ database 
     832    private String getType(String type) 
     833    { 
     834        String read; 
     835        try 
     836        { 
     837            BufferedReader in = new BufferedReader(new FileReader(this.files_home_dir + "files" + File.separator + "pointdes.txt")); 
     838            in.readLine(); 
     839            while (in.ready()) 
     840            { 
     841                read = in.readLine(); 
     842                if (read.substring(0, read.indexOf('`')).toLowerCase().equals(type.toLowerCase())) 
     843                { 
     844                    in.close(); 
     845                    return read.substring(read.indexOf('`') + 1, read.indexOf(':')); 
     846                } 
     847            } 
     848        } 
     849        catch (Exception e) 
     850        { 
     851        } 
     852        return ""; 
    189853    } 
    190     result.setAttribute(GSXML.FROM_ATT, DOCUMENT_METADATA_RETRIEVE_SERVICE); 
    191     result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS); 
    192  
    193     // Get the parameters of the request 
    194     Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER); 
    195     if (param_list == null) { 
    196         logger.error("missing paramList.\n"); 
    197         return result;  // Return the empty result 
     854 
     855    //recursive pre-order traversal of the 2-dimensional tree 
     856    // x & y are co-ordinates of mouse click, xoff & yoff are the distance in degrees away from x & y to search, 
     857    // d is the current node of the tree, xcomp controls whether searching is by x co-ordinate or y co-ordinate. 
     858    private void findName(double x, double y, double xoff, double yoff, DefaultMutableTreeNode d, boolean xcomp) 
     859    { 
     860        //if a leaf node return.  All leaf nodes are empty 
     861        if (d.isLeaf()) 
     862            return; 
     863        //get coordinates of the current node 
     864        double xco = Double.parseDouble(((String) d.getUserObject()).substring(((String) d.getUserObject()).length() - 6, ((String) d.getUserObject()).length())); 
     865        double yco = Double.parseDouble(((String) d.getUserObject()).substring(((String) d.getUserObject()).length() - 12, ((String) d.getUserObject()).length() - 7)); 
     866        //if in range 
     867        if ((x - xoff) < xco && (x + xoff) > xco && (y - yoff) < yco && (y + yoff) > yco) 
     868        { 
     869            //add to list 
     870            namesInList.addFirst((String) d.getUserObject()); 
     871        } 
     872        //if comparing the x axis 
     873        if (xcomp) 
     874        { 
     875            //if need to search left subtree 
     876            if ((x - xoff) < xco) 
     877                findName(x, y, xoff, yoff, (DefaultMutableTreeNode) d.getChildAt(0), !xcomp); 
     878            //if need to search right subtree 
     879            if ((x + xoff) > xco) 
     880                findName(x, y, xoff, yoff, (DefaultMutableTreeNode) d.getChildAt(1), !xcomp); 
     881        } 
     882        else 
     883        { 
     884            //if need to search left subtree 
     885            if ((y - yoff) < yco) 
     886                findName(x, y, xoff, yoff, (DefaultMutableTreeNode) d.getChildAt(0), !xcomp); 
     887            //if need to search right subtree 
     888            if ((y + yoff) > yco) 
     889                findName(x, y, xoff, yoff, (DefaultMutableTreeNode) d.getChildAt(1), !xcomp); 
     890        } 
    198891    } 
    199892 
    200     // The metadata information required 
    201     Vector<String> metadata_list = new Vector<String>(); 
    202     boolean all_metadata = false; 
    203     // Process the request parameters 
    204     Element param = GSXML.getFirstElementChild(param_list);//(Element) param_list.getFirstChild(); 
    205  
    206     while (param != null) { 
    207         // Identify the metadata information desired 
    208         if (param.getAttribute(GSXML.NAME_ATT).equals("metadata")) { 
    209         String metadata = GSXML.getValue(param); 
    210         if (metadata.equals("all")) { 
    211             all_metadata = true; 
    212             break; 
    213         } 
    214         metadata_list.add(metadata); 
    215         } 
    216         param = (Element) param.getNextSibling(); 
     893    // a whole lot of stuff for the html that is hidden at the bottom here because it clutters more than I already have further up! 
     894    private String getJavascript(double ratio, String doc_id, int leg_num) 
     895    { 
     896        String javascript = "\n<script>\nfunction imgClickHandler (evt, img, num) {\n\tif (window.event){\n\t\tvar chooserString = 'placeChooserImage' + '```' + window.event.offsetX + '`' + window.event.offsetY\n\t\tmywindow = window.open(chooserString,'Choose','width=600, height=500, scrollbars=yes, resizable=yes, toolbar=no, location=no, status=yes, menubar=no');\n\t\t//alert(window.event.offsetX + ':' + window.event.offsetY + ':' + num);\n\t}\n\telse if (evt.target) {\n\t\tvar coords = {x: 0, y: 0 };\n\t\tvar el = evt.target;\n\t\tdo {\n\t\t\tcoords.x += el.offsetLeft;\n\t\t\tcoords.y += el.offsetTop;\n\t\t}\n\t\twhile ((el = el.offsetParent));\n\t\tvar offsetX = evt.clientX - coords.x;\n\t\tvar offsetY = evt.clientY - coords.y;\n\t\talert(offsetX + ':' + offsetY + ':' + num);\n\t}\n}\nfunction leapTo (link)\n{\n\tvar new_url=link;\n\tif (  (new_url != \"\")  &&  (new_url != null)  ) \n\t\twindow.location=new_url;\n\telse \n\t\talert(\"You must make a selection.\");\n}\nfunction jumpTo (front,link,back)\n{\n\tvar new_url=front+link+back;\n\tif (  (new_url != \"\")  &&  (new_url != null)  ) \n\t\twindow.location=new_url;\n\telse \n\t\talert(\"You must make a selection.\");\n}// Deactivate Cloaking -->\n</script>"; 
     897 
     898        String radioButtons = "\n<center><FORM>"; 
     899        if (ratio != 0.4) 
     900            radioButtons = radioButtons + "\n\t<INPUT TYPE=\"radio\" NAME=\"buttons1\" onClick=\"leapTo('zoomhead" + doc_id + "`0.4')\">40%"; 
     901        if (ratio != 0.5) 
     902            radioButtons = radioButtons + "\n\t<INPUT TYPE=\"radio\" NAME=\"buttons1\" onClick=\"leapTo('zoomhead" + doc_id + "`0.5')\">50%"; 
     903        if (ratio != 0.6) 
     904            radioButtons = radioButtons + "\n\t<INPUT TYPE=\"radio\" NAME=\"buttons1\" onClick=\"leapTo('zoomhead" + doc_id + "`0.6')\">60%"; 
     905        if (ratio != 0.7) 
     906            radioButtons = radioButtons + "\n\t<INPUT TYPE=\"radio\" NAME=\"buttons1\" onClick=\"leapTo('zoomhead" + doc_id + "`0.7')\">70%"; 
     907        if (ratio != 0.8) 
     908            radioButtons = radioButtons + "\n\t<INPUT TYPE=\"radio\" NAME=\"buttons1\" onClick=\"leapTo('zoomhead" + doc_id + "`0.8')\">80%"; 
     909        if (ratio != 0.9) 
     910            radioButtons = radioButtons + "\n\t<INPUT TYPE=\"radio\" NAME=\"buttons1\" onClick=\"leapTo('zoomhead" + doc_id + "`0.9')\">90%"; 
     911        if (ratio != 1.0) 
     912            radioButtons = radioButtons + "\n\t<INPUT TYPE=\"radio\" NAME=\"buttons1\" onClick=\"leapTo('zoomhead" + doc_id + "`1.0')\">100%"; 
     913        radioButtons = radioButtons + "\n</FORM></center>"; 
     914 
     915        leg_num = leg_num + 1; 
     916 
     917        String doc_link = "?a=d&c=" + this.cluster_name + "&dt=map&d=" + doc_id + "`" + ratio + "`" + leg_num + "`"; 
     918 
     919        StringBuffer dropDownBox = new StringBuffer(); 
     920 
     921        dropDownBox.append("Add Locations Of Type: <form name=\"myForm\"><select name=\"s1index\" onChange=\"jumpTo('"); 
     922        dropDownBox.append(doc_link); 
     923        dropDownBox.append("',document.myForm.s1index.options[document.myForm.s1index.selectedIndex].value,'')\">\n"); 
     924 
     925        for (int i = 0; i < this.index_name_list.size(); i++) 
     926        { 
     927            String name = this.index_name_list.get(i); 
     928            dropDownBox.append("<option value=\""); 
     929            dropDownBox.append(name); 
     930            dropDownBox.append("\">"); 
     931            String display = this.index_display_list.get(i); 
     932            dropDownBox.append(display); 
     933            dropDownBox.append("\n"); 
     934        } 
     935        // for each option, Malcolm had onClick=\"leapTo('"+doc_link+name+"')\" - dont seem to need this 
     936        dropDownBox.append("</select></form>\n"); 
     937 
     938        return javascript + radioButtons + dropDownBox; 
    217939    } 
    218  
    219     Element node_list = this.doc.createElement(GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER); 
    220     result.appendChild(node_list); 
    221      
    222     // Get the documents 
    223     Element request_node_list = (Element) GSXML.getChildByTagName(request, GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER); 
    224     if (request_node_list == null) { 
    225         logger.error(" DocumentMetadataRetrieve request had no "+GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER); 
    226         return result; 
    227     } 
    228  
    229     NodeList request_nodes = request_node_list.getChildNodes(); 
    230  
    231     try{ 
    232         //used just to ensure outfile is initialised 
    233         BufferedWriter outfile = new BufferedWriter(new FileWriter(this.temp_files_dir+"emptynothingness")); 
    234          
    235         for (int i = 0; i < request_nodes.getLength(); i++) { 
    236         Element request_node = (Element) request_nodes.item(i); 
    237         String node_id = request_node.getAttribute(GSXML.NODE_ID_ATT); 
    238         String place_data = ""; 
    239         String year = ""; 
    240         String coOrdinates = ""; 
    241         String thumb = ""; 
    242         String link = ""; 
    243         int mapFreq = 0; 
    244         LinkedList place_data_list = new LinkedList(); 
    245         LinkedList coOrdinates_list = new LinkedList(); 
    246  
    247         //if this is a first displaying of the map 
    248         if(node_id.indexOf("```") != -1 && node_id.indexOf("imageChooser") == -1){ 
    249             //get the number of query terms on this map 
    250             mapFreq = Integer.parseInt(node_id.substring(node_id.lastIndexOf('`',node_id.indexOf("```")-1)+1,node_id.indexOf("```"))); 
    251             //get the place names on this map 
    252             place_data = node_id.substring(node_id.indexOf("```")+3,node_id.length()); 
    253             //get the map metadata 
    254             node_id = node_id.substring(0,node_id.indexOf('`',node_id.indexOf("```"))); 
    255              
    256             try{ 
    257             // loop for each query term on the map 
    258             for(int r=0; r<mapFreq; r++){ 
    259                 // get title, type, location, and the string for creating the hyperlink for this query term 
    260                 String title = place_data.substring(0,place_data.indexOf('`')); 
    261                 String type = place_data.substring(place_data.indexOf('`')+1,place_data.indexOf('`',place_data.indexOf('`')+1)); 
    262                 String location = place_data.substring(place_data.indexOf('`',place_data.indexOf('`')+1)+1, place_data.indexOf('`',place_data.indexOf('`',place_data.indexOf('`')+1)+1)); 
    263                 if(place_data.indexOf("```") != -1) 
    264                 link=place_data.substring(0,place_data.indexOf("```")); 
    265                 else 
    266                 link=place_data; 
    267                 // resolve the type and location 
    268                 type = getType(type); 
    269                 location = getLocation(location); 
    270                 // remove this query term from the string 
    271                 if(place_data.indexOf("```") != -1) 
    272                 place_data = place_data.substring(place_data.indexOf("```")+3,place_data.length()); 
    273                  
    274                 //add the co-ordinates of this query term to the co-ordinates list 
    275                 coOrdinates_list.add("`"+link.substring(link.lastIndexOf('`')+1,link.length())+"`"+link.substring(link.lastIndexOf('`',link.lastIndexOf('`')-1)+2,link.lastIndexOf('`'))); 
    276                  
    277                 // add the title, type and location to the places list 
    278                 place_data_list.add(title + ", " + type + ", " + location + ";"); 
    279             } 
    280             }catch(StringIndexOutOfBoundsException sioobe){sioobe.printStackTrace();} 
    281         } 
    282          
    283         // Add the document to the list 
    284         Element new_node = (Element)this.doc.importNode(request_node, false); 
    285         node_list.appendChild(new_node); 
    286          
    287         // Add the requested metadata information 
    288         Element node_meta_list = this.doc.createElement(GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER); 
    289         new_node.appendChild(node_meta_list); 
    290          
    291         // create the navigation thumbnails.  This doesn't seem to work most of the time ??????? 
    292         for (int m = 0; m < metadata_list.size(); m++) { 
    293             String metadata = metadata_list.get(m); 
    294             thumb = ""; 
    295             String value = ""; 
    296             if(node_id.indexOf('.') != -1)  
    297             thumb = node_id.substring(0,node_id.indexOf('.')); 
    298             if(node_id.indexOf('`') != -1)  
    299             value = node_id.substring(node_id.lastIndexOf('`',node_id.lastIndexOf('`')-1)+1,node_id.lastIndexOf('`',node_id.lastIndexOf('`')-1)+5); 
    300             year = value; 
    301              
    302             place_data=""; 
    303             if(place_data_list.size() != 0) 
    304             for(int q=0; q<mapFreq; q++){ 
    305                 link = (String)place_data_list.get(q); 
    306                 if(q!=0){ 
    307                 place_data = place_data + "<br>" + link; 
    308                 } 
    309                 else{ 
    310                 place_data = link; 
    311                 coOrdinates = "``"; 
    312                 } 
    313                 coOrdinates = coOrdinates+(String)coOrdinates_list.get(q); 
    314             } 
    315              
    316             link = "<a href=\"?a=d&c="+this.cluster_name+"&d="+node_id+coOrdinates+"&dt=map\">"; 
    317             thumb = "<img src=\""+this.http_image_dir + thumb + "thumb.jpg\" border=0>"; 
    318             value = "<table><tr><td>"+link+"<p>"+place_data+"<br>"+value+"</a></td><td>"+link+thumb+"</a></td></tr></table>"; 
    319             if(metadata.equals("Title")) 
    320             if(!(place_data.equals("")) && place_data.indexOf(", , ;")==-1 && node_id.indexOf("```")==-1) 
    321                 GSXML.addMetadata(this.doc, node_meta_list, "Title", value);//metadata, value); 
    322             else 
    323                 GSXML.addMetadata(this.doc, node_meta_list, metadata, ""); 
    324              
    325             if(place_data.indexOf(", , ;")==-1){ 
    326             if(i==0) 
    327                 if(!(mapFreq==0)){ 
    328                 outfile = new BufferedWriter(new FileWriter(this.temp_files_dir+"links"+uid)); 
    329                 outfile.write("<table align=\"center\"><tr>"); 
    330                 } 
    331              
    332             if(!(mapFreq==0)){ 
    333                 if(i%7 == 0) 
    334                 outfile.write("</tr><tr>"); 
    335                 outfile.write("<td align=\"center\">"+link+thumb+"</a><br>"+link+year+"</a></td>"); 
    336             } 
    337              
    338             if(i == request_nodes.getLength()-1){ 
    339                 outfile.write("</tr></table><p>"); 
    340                 outfile.flush(); 
    341                 outfile.close(); 
    342             } 
    343             } 
    344         }  
    345          
    346         } 
    347     }catch(IOException ioe){ioe.printStackTrace();} 
    348      
    349     return result; 
    350     }catch(Exception excep){excep.printStackTrace();} 
    351     return null; 
    352  
    353     } 
    354  
    355     protected Element processDocumentContentRetrieve(Element request){ 
    356     // Create a new (empty) result message 
    357     Element result = doc.createElement(GSXML.RESPONSE_ELEM); 
    358     result.setAttribute(GSXML.FROM_ATT, DOCUMENT_CONTENT_RETRIEVE_SERVICE); 
    359     result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS); 
    360      
    361     String uid = request.getAttribute(GSXML.USER_ID_ATT); 
    362     String temp_image_file = this.temp_files_dir+"temp_"+uid+".jpg"; 
    363     String temp_image_file2 = this.temp_files_dir+"temp_"+uid+"_2.jpg"; 
    364  
    365     Element query_doc_list = (Element) GSXML.getChildByTagName(request, GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER); 
    366     if (query_doc_list == null) { 
    367         logger.error("DocumentContentRetrieve request specified no doc nodes.\n"); 
    368         return result; 
    369     } 
    370      
    371     String legend_file = this.temp_files_dir+"legend_"+uid+".jpg"; 
    372     String blank_file = this.files_home_dir + "blank.jpg"; 
    373     Element doc_list = doc.createElement(GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER); 
    374     result.appendChild(doc_list); 
    375      
    376     // Get the documents 
    377     String[] doc_ids = GSXML.getAttributeValuesFromList(query_doc_list,  
    378                                  GSXML.NODE_ID_ATT); 
    379  
    380     for (int i = 0; i < doc_ids.length; i++) { 
    381         String doc_id = doc_ids[i]; 
    382         // img_num is the name of the map file eg. 072.jpg 
    383         String img_num = doc_id.substring(0,doc_id.indexOf('.')); 
    384         // strings for inserting image in html 
    385         String img_left = "<img border=0 src=\""+this.http_temp_image_dir; 
    386         String doc_content = ""; 
    387         String co_ordinates = ""; 
    388         String img_size = ""; 
    389         int height = 0; 
    390         int width = 0; 
    391         // the number for the legend image if adding locations to the map 
    392         int leg_num = 0; 
    393         double ratio = 0; 
    394  
    395         // if user has clicked on the map.  This does not resolve maps that are not North oriented. 
    396         if(doc_id.indexOf("imageChooser")==0){ 
    397         try{ 
    398             doc_id = doc_id.substring(doc_id.indexOf('`')+1,doc_id.length()); 
    399             img_num = doc_id.substring(0,doc_id.indexOf('.')); 
    400  
    401             // get the map size 
    402             String get_size[] = {"identify","-size","10000", temp_image_file}; 
    403             Process proc; 
    404             proc = Runtime.getRuntime().exec(get_size); 
    405             BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream())); 
    406             img_size = br.readLine(); 
    407             proc.waitFor(); 
    408             img_size = img_size.substring(img_size.indexOf("JPEG")+5,img_size.indexOf(" ",img_size.indexOf("JPEG")+5)); 
    409             width = Integer.parseInt(img_size.substring(0,img_size.indexOf("x"))); 
    410             height = Integer.parseInt(img_size.substring(img_size.indexOf("x")+1,img_size.length())); 
    411  
    412             // scale image size according to the ratio 
    413             ratio = Double.parseDouble(doc_id.substring(doc_id.lastIndexOf('`',doc_id.indexOf("```")-1)+1,doc_id.indexOf("```"))); 
    414             width = (int)(width*ratio); 
    415             height = (int)(height*ratio); 
    416  
    417             // get the position of the mouse click on the image 
    418             int xclick = Integer.parseInt(doc_id.substring(doc_id.indexOf("```")+3,doc_id.lastIndexOf('`'))); 
    419             int yclick = Integer.parseInt(doc_id.substring(doc_id.lastIndexOf('`')+1,doc_id.length())); 
    420             doc_id = doc_id.substring(doc_id.indexOf('`')+1,doc_id.indexOf("```")); 
    421  
    422             // convert click position to percentage distance accross and down the image. 
    423             double xpercent = (xclick*1.0)/width; 
    424             double ypercent = (yclick*1.0)/height; 
    425  
    426             // get the top left and bottom right co-ordinates of the map 
    427             double ytop = Double.parseDouble(doc_id.substring(0,doc_id.indexOf('`')))*-1; 
    428             doc_id = doc_id.substring(doc_id.indexOf('`')+1,doc_id.length()); 
    429             double xleft = Double.parseDouble(doc_id.substring(0,doc_id.indexOf('`'))); 
    430             doc_id = doc_id.substring(doc_id.indexOf('`')+1,doc_id.length()); 
    431             double ybot = Double.parseDouble(doc_id.substring(0,doc_id.indexOf('`')))*-1; 
    432             doc_id = doc_id.substring(doc_id.indexOf('`')+1,doc_id.length()); 
    433             double xright = Double.parseDouble(doc_id.substring(0,doc_id.indexOf('`'))); 
    434             doc_id = doc_id.substring(doc_id.indexOf('`')+1,doc_id.length()); 
    435  
    436             // calculate the map co-ordinates of the mouse click 
    437             xpercent = ((xright-xleft)*xpercent)+xleft; 
    438             ypercent = ((ybot-ytop)*ypercent)+ytop; 
    439  
    440             // search the tree for nearby place names 
    441             namesInList.clear(); 
    442             findName(xpercent, ypercent, 0.1, 0.1, tree, true); 
    443  
    444             int namesInArraySize = namesInList.size(); 
    445             String returnNames[]=new String[namesInArraySize]; 
    446  
    447             //put the names in an array 
    448             for(int ri=0; namesInList.size()>0; ri++){ 
    449             returnNames[ri]=namesInList.getFirst(); 
    450             returnNames[ri] = returnNames[ri].substring(0,returnNames[ri].indexOf('`')); 
    451             namesInList.removeFirst(); 
    452             } 
    453  
    454             //sort the names 
    455             Arrays.sort(returnNames); 
    456             doc_content = "\n<script>\nfunction openIt(loc){\n\topener.location=loc;\n\tself.close();\n}\n</script>"; 
    457             for(int nameIndex=0; nameIndex < namesInArraySize; nameIndex++){ 
    458             String tempName = returnNames[nameIndex]; 
    459             //convert names with spaces for hyperlinks 
    460             if(returnNames[nameIndex].indexOf(' ') != -1){ 
    461                 returnNames[nameIndex] = returnNames[nameIndex].replaceAll(" ","+"); 
    462                 returnNames[nameIndex] = "%22"+returnNames[nameIndex]+"%22"; 
    463             } 
    464             // add the place name to the html 
    465             doc_content = doc_content+"<a href=\"\" onClick=openIt('?a=q&sa=&rt=r&s=MapQuery&c="+this.cluster_name+"&startPage=1&s1.index=none&s1.maxDocs=10&s1.query="+returnNames[nameIndex]+"')>"+tempName+"</a><br>"; 
    466             } 
    467              
    468         }catch(Exception ioexception){ioexception.printStackTrace();} 
    469         } 
    470         else{ 
    471          
    472         try{ 
    473             //file for converting image     
    474             BufferedWriter bw = new BufferedWriter(new FileWriter(this.temp_files_dir + "add_x_"+uid));; 
    475             Process proc; 
    476              
    477             // if a new search 
    478             if(doc_id.indexOf("```") != -1){ 
    479             // copy requested map to temp.jpg 
    480             proc = Runtime.getRuntime().exec("cp "+this.files_home_dir+"maps"+File.separator+img_num+".jpg "+temp_image_file); 
    481             proc.waitFor(); 
    482             } 
    483  
    484             //get the image size 
    485             String get_size[] = {"identify","-size","10000", temp_image_file}; 
    486             proc = Runtime.getRuntime().exec(get_size); 
    487             BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream())); 
    488             img_size = br.readLine(); 
    489             proc.waitFor(); 
    490             img_size = img_size.substring(img_size.indexOf("JPEG")+5,img_size.indexOf(" ",img_size.indexOf("JPEG")+5)); 
    491             if (img_size.indexOf("+")!=-1) { 
    492             img_size = img_size.substring(0, img_size.indexOf("+")); 
    493             } 
    494             width = Integer.parseInt(img_size.substring(0,img_size.indexOf("x"))); 
    495             height = Integer.parseInt(img_size.substring(img_size.indexOf("x")+1,img_size.length())); 
    496              
    497             // if a new search 
    498             if(doc_id.indexOf("```") != -1){ 
    499             co_ordinates = doc_id.substring(doc_id.indexOf("```")+2, doc_id.length()); 
    500             // get the number of places to mark on the map 
    501             int x_number = Integer.parseInt(doc_id.substring(doc_id.lastIndexOf('`',doc_id.indexOf("```")-1)+1,doc_id.indexOf("```"))); 
    502  
    503             //write the convert command 
    504             bw.write("convert -font helvetica -fill red -pointsize 48 "); 
    505  
    506             for(int xi=0; xi<x_number; xi++){ 
    507  
    508                 // get the co-ordinates of the place name 
    509                 double xco = Double.parseDouble(co_ordinates.substring(co_ordinates.lastIndexOf('`',co_ordinates.lastIndexOf('`')-1)+1,co_ordinates.lastIndexOf('`',co_ordinates.lastIndexOf('`')-1)+7)); 
    510                 double yco = Double.parseDouble(co_ordinates.substring(co_ordinates.lastIndexOf('`')+1,co_ordinates.length())); 
    511                 if(xi != x_number-1) 
    512                 co_ordinates = co_ordinates.substring(0,co_ordinates.lastIndexOf('`',co_ordinates.lastIndexOf('`')-1)); 
    513              
    514                 int index = 0; 
    515                 index = doc_id.indexOf('`')+2; 
    516                  
    517                 // get the zoom ratio and the top left and bottom right co-ordinates of the map 
    518                 ratio = 0.4; 
    519                 double tly = Double.parseDouble(doc_id.substring(index,index+5)); 
    520                 index = doc_id.indexOf('`',index)+1; 
    521                 double tlx = Double.parseDouble(doc_id.substring(index,index+6)); 
    522                 index = doc_id.indexOf('`',index)+2; 
    523                 double bry = Double.parseDouble(doc_id.substring(index,index+5)); 
    524                 index = doc_id.indexOf('`',index)+1; 
    525                 double brx = Double.parseDouble(doc_id.substring(index,index+6)); 
    526                 index = doc_id.indexOf('`',index)+1; 
    527                 double orient = Double.parseDouble(doc_id.substring(index,doc_id.indexOf('`',index))); 
    528  
    529                 // find the centre of the map 
    530                 double xcent = ((brx-tlx)/2)+tlx; 
    531                 double ycent = ((bry-tly)/2)+tly; 
    532  
    533                 // get the orientation of the map 
    534                 orient = Math.toRadians(orient); 
    535  
    536                 // rotate the co-ordinates around the centre of the map  
    537                 xco=xco-xcent; 
    538                 yco=yco-ycent; 
    539                 double oldx=xco; 
    540                 xco=xco*Math.cos(orient)-yco*Math.sin(orient); 
    541                 yco=oldx*Math.sin(orient)+yco*Math.cos(orient); 
    542                 xco=xco+xcent; 
    543                 yco=yco+ycent; 
    544                 xco = (xco-tlx)/(brx-tlx); 
    545                 yco = (yco-tly)/(bry-tly); 
    546  
    547                 // calculate the pixels for placing the mark 
    548                 width = (int)(xco*width)-5; 
    549                 height = (int)(yco*height)-5; 
    550              
    551                 // write the options for convert 
    552                 bw.write("-draw 'text "+width+","+height+" \"x\"' "); 
    553                 bw.flush(); 
    554              
    555                 // reset the width and height variables for the image 
    556                 width = Integer.parseInt(img_size.substring(0,img_size.indexOf("x"))); 
    557                 height = Integer.parseInt(img_size.substring(img_size.indexOf("x")+1,img_size.length())); 
    558             } 
    559             doc_id = doc_id.substring(0,doc_id.lastIndexOf('`',doc_id.indexOf("```")-1)); 
    560  
    561             // write the end of the convert command, then command for zooming image to the right level, then command to copy the blank image over legend.jpg 
    562             bw.write(temp_image_file+" "+temp_image_file+";convert -scale "+((int)(ratio*width))+"x"+((int)(ratio*height))+" "+temp_image_file+" "+temp_image_file2+";cp "+blank_file +" "+legend_file); 
    563  
    564             // reset legend number 
    565             leg_num = 0; 
    566             } 
    567  
    568             else 
    569             // if changing zoom level 
    570             if(doc_id.substring(doc_id.lastIndexOf('`'),doc_id.length()).indexOf('.')!=-1){ 
    571                 // get the ratio 
    572                 ratio = Double.parseDouble(doc_id.substring(doc_id.lastIndexOf('`')+1,doc_id.length())); 
    573                 // write the command for scaling image 
    574                 bw.write("convert -scale "+((int)(ratio*width))+"x"+((int)(ratio*height))+" "+temp_image_file+" "+temp_image_file2); 
    575                 doc_id = doc_id.substring(0,doc_id.lastIndexOf('`')); 
    576             } 
    577  
    578                 // if adding locations to map 
    579             else{ 
    580  
    581                 // get the location type to add 
    582                 String restricter= doc_id.substring(doc_id.lastIndexOf('`')+1,doc_id.length()); 
    583                 doc_id = doc_id.substring(0,doc_id.lastIndexOf('`')); 
    584  
    585                 // get the number for the legend image 
    586                 leg_num = Integer.parseInt(doc_id.substring(doc_id.lastIndexOf('`')+1,doc_id.length())); 
    587                 doc_id = doc_id.substring(0,doc_id.lastIndexOf('`')); 
    588  
    589                 //open file for location type 
    590                 BufferedReader inType = new BufferedReader(new FileReader(this.files_home_dir + "place_types"+File.separator + restricter + ".txt")); 
    591  
    592                 //check through the file and add any places that are in the bounds of this map. 
    593  
    594                 // check value. set to true if a place to add is found 
    595                 boolean add_place_type = false; 
    596  
    597                 int index = 0; 
    598                 index = doc_id.indexOf('`')+2; 
    599                 // get zoom ratio 
    600                 ratio = Double.parseDouble(doc_id.substring(doc_id.lastIndexOf('`')+1,doc_id.length())); 
    601                 // get top left and bottom right co-ordinates of the map 
    602                 double tly = Double.parseDouble(doc_id.substring(index,index+5)); 
    603                 index = doc_id.indexOf('`',index)+1; 
    604                 double tlx = Double.parseDouble(doc_id.substring(index,index+6)); 
    605                 index = doc_id.indexOf('`',index)+2; 
    606                 double bry = Double.parseDouble(doc_id.substring(index,index+5)); 
    607                 index = doc_id.indexOf('`',index)+1; 
    608                 double brx = Double.parseDouble(doc_id.substring(index,index+6)); 
    609                 index = doc_id.indexOf('`',index)+1; 
    610                 // get orientation of the map 
    611                 double orient = Double.parseDouble(doc_id.substring(index,doc_id.indexOf('`',index))); 
    612                 // calculate centre of map 
    613                 double xcent = ((brx-tlx)/2)+tlx; 
    614                 double ycent = ((bry-tly)/2)+tly; 
    615                 orient = Math.toRadians(orient); 
    616  
    617                 String type_point = ""; 
    618                 double xco = 0.0; 
    619                 double yco = 0.0; 
    620  
    621                 // read the file 
    622                 while(inType.ready()){ 
    623                 //read a line 
    624                 type_point = inType.readLine(); 
    625  
    626                 // get the co-ordinates of the point 
    627                 xco = Double.parseDouble(type_point.substring(type_point.lastIndexOf('`')+1,type_point.length())); 
    628                 yco = Double.parseDouble(type_point.substring(type_point.lastIndexOf('`',type_point.lastIndexOf('`')-1)+2,type_point.lastIndexOf('`'))); 
    629  
    630                 // if it is within the co-ordinates of the map 
    631                 if(xco >= tlx && xco < brx && yco >= tly && yco < bry){ 
    632                     // rotate the point around the centre according to map orientation 
    633                     xco=xco-xcent; 
    634                     yco=yco-ycent; 
    635                     double oldx=xco; 
    636                     xco=xco*Math.cos(orient)-yco*Math.sin(orient); 
    637                     yco=oldx*Math.sin(orient)+yco*Math.cos(orient); 
    638                     xco=xco+xcent; 
    639                     yco=yco+ycent; 
    640                     // get the pixels for where to place the mark 
    641                     xco = (xco-tlx)/(brx-tlx); 
    642                     yco = (yco-tly)/(bry-tly); 
    643                     width = (int)(xco*width)-5; 
    644                     height = (int)(yco*height)-5; 
    645  
    646                     //if this is the first point to be added 
    647                     if(!add_place_type){ 
    648                     // write the initial convert command 
    649                     bw.write("convert -font helvetica -fill red -pointsize 36 "); 
    650                     // toggle check value 
    651                     add_place_type = true; 
    652                     } 
    653  
    654                     // write the options for the convert command 
    655                     bw.write("-draw 'text "+width+","+height+" \""+leg_num+"\"' "); 
    656                     bw.flush(); 
    657              
    658                     // reset width and height variables for the image 
    659                     width = Integer.parseInt(img_size.substring(0,img_size.indexOf("x"))); 
    660                     height = Integer.parseInt(img_size.substring(img_size.indexOf("x")+1,img_size.length())); 
    661                 } 
    662                 } 
    663  
    664                 //if there are places to mark on the map 
    665                 if(add_place_type){ 
    666                 // finish the convert command and write command for scaling image 
    667                 bw.write(temp_image_file+" "+temp_image_file+";convert -scale "+((int)(ratio*width))+"x"+((int)(ratio*height))+" "+temp_image_file+" "+temp_image_file2); 
    668  
    669                 // open file for converting the legend command 
    670                 BufferedWriter buf = new BufferedWriter(new FileWriter(this.temp_files_dir+"add_l_"+uid)); 
    671                 if(leg_num == 1) 
    672                     buf.write("cp "+blank_file +" "+legend_file+";"); 
    673                 // write the command for adding to the legend 
    674                 buf.write("convert -font helvetica -fill red -pointsize 12 -draw 'text 15,"+(leg_num*15+20)+" \""+leg_num+" "+getType(restricter)+"\"' "+legend_file+" "+legend_file); 
    675                 buf.flush(); 
    676                 buf.close(); 
    677                 // execute the command for the legend image 
    678                 proc = Runtime.getRuntime().exec("sh "+this.temp_files_dir+"add_l_"+uid); 
    679                 proc.waitFor(); 
    680                 } 
    681                 inType.close(); 
    682             } 
    683             bw.flush(); 
    684             bw.close(); 
    685          
    686             // execute the convert commands etc. 
    687             proc = Runtime.getRuntime().exec("sh "+this.temp_files_dir+"add_x_"+uid); 
    688             proc.waitFor(); 
    689          
    690         }catch(Exception ioe){ioe.printStackTrace();} 
    691  
    692         //write the html for the document 
    693  
    694         String doc_content_head = "?a=d&c="+this.cluster_name+"&dt=map&d="; 
    695         doc_content = "<td valign=\"top\"><script>document.write('"+img_left+"legend_"+uid+".jpg"+"?'+new Date().getTime())</script>\"></td>"; 
    696         doc_content = doc_content+"<td><script>document.write('"+img_left+"temp_"+uid+"_2.jpg?'+new Date().getTime())</script>\" onclick=\"imgClickHandler(event, this, '"+img_num+"')\"></td>"; 
    697  
    698         // replace _httpimg_ with the correct address 
    699         doc_content = "<table><tr>"+doc_content+"</tr></table>"; 
    700  
    701         String javascript = getJavascript(ratio, doc_id, leg_num); 
    702  
    703         doc_content = "<center>You are currently viewing the map at "+(int)(ratio*100)+"%<br>Select a radio button for a new zoom level.</center>"+javascript+doc_content; 
    704         doc_content = doc_content.replaceAll("zoomhead", doc_content_head); 
    705         doc_content = doc_content.replaceAll("placeChooserImage", doc_content_head+"imageChooser`"+doc_id+"`"+ratio); 
    706  
    707         // read the file for the navigation thumbnails 
    708         try{ 
    709             BufferedReader infile = new BufferedReader(new FileReader(this.temp_files_dir+"links"+uid)); 
    710             doc_content = doc_content + infile.readLine(); 
    711             infile.close(); 
    712         }catch(Exception ioexc){ioexc.printStackTrace();} 
    713         } 
    714  
    715         // put the html in a text node 
    716         Element text_doc = doc.createElement(GSXML.DOC_NODE_ELEM); 
    717         text_doc.setAttribute(GSXML.NODE_ID_ATT, doc_id); 
    718         GSXML.addDocText(doc, text_doc, doc_content); 
    719         doc_list.appendChild(text_doc); 
    720          
    721     } 
    722         return result; 
    723     } 
    724  
    725     // resolves location codes for places from LINZ database 
    726     private String getLocation(String location){ 
    727     String read; 
    728     try{ 
    729         BufferedReader in = new BufferedReader(new FileReader(this.files_home_dir+"files"+File.separator+"landdist.txt")); 
    730         in.readLine(); 
    731         while(in.ready()){ 
    732         read = in.readLine(); 
    733         if(read.substring(0,2).equals(location)){ 
    734             in.close(); 
    735             return read.substring(3, read.length()); 
    736         } 
    737         } 
    738     }catch(Exception e){} 
    739     return ""; 
    740     } 
    741  
    742     // resolves type codes for the LINZ database 
    743     private String getType(String type){ 
    744     String read; 
    745     try{ 
    746         BufferedReader in = new BufferedReader(new FileReader(this.files_home_dir+"files"+File.separator+"pointdes.txt")); 
    747         in.readLine(); 
    748         while(in.ready()){ 
    749         read = in.readLine(); 
    750         if(read.substring(0,read.indexOf('`')).toLowerCase().equals(type.toLowerCase())){ 
    751             in.close(); 
    752             return read.substring(read.indexOf('`')+1, read.indexOf(':')); 
    753         } 
    754         } 
    755     }catch(Exception e){} 
    756     return ""; 
    757     } 
    758  
    759     //recursive pre-order traversal of the 2-dimensional tree 
    760     // x & y are co-ordinates of mouse click, xoff & yoff are the distance in degrees away from x & y to search, 
    761     // d is the current node of the tree, xcomp controls whether searching is by x co-ordinate or y co-ordinate. 
    762     private void findName(double x, double y, double xoff, double yoff, DefaultMutableTreeNode d, boolean xcomp){ 
    763     //if a leaf node return.  All leaf nodes are empty 
    764     if(d.isLeaf()) 
    765         return; 
    766     //get coordinates of the current node 
    767     double xco = Double.parseDouble(((String)d.getUserObject()).substring(((String)d.getUserObject()).length()-6,((String)d.getUserObject()).length())); 
    768     double yco = Double.parseDouble(((String)d.getUserObject()).substring(((String)d.getUserObject()).length()-12,((String)d.getUserObject()).length()-7)); 
    769     //if in range 
    770     if((x-xoff)<xco && (x+xoff)>xco && (y-yoff)<yco && (y+yoff)>yco){ 
    771         //add to list 
    772         namesInList.addFirst((String)d.getUserObject()); 
    773     } 
    774     //if comparing the x axis 
    775     if(xcomp){ 
    776         //if need to search left subtree 
    777         if((x-xoff)<xco) 
    778         findName(x,y,xoff,yoff,(DefaultMutableTreeNode)d.getChildAt(0),!xcomp); 
    779         //if need to search right subtree 
    780         if((x+xoff)>xco) 
    781         findName(x,y,xoff,yoff,(DefaultMutableTreeNode)d.getChildAt(1),!xcomp); 
    782     } 
    783     else{ 
    784         //if need to search left subtree 
    785         if((y-yoff)<yco) 
    786         findName(x,y,xoff,yoff,(DefaultMutableTreeNode)d.getChildAt(0),!xcomp); 
    787         //if need to search right subtree 
    788         if((y+yoff)>yco) 
    789         findName(x,y,xoff,yoff,(DefaultMutableTreeNode)d.getChildAt(1),!xcomp); 
    790     } 
    791     } 
    792  
    793     // a whole lot of stuff for the html that is hidden at the bottom here because it clutters more than I already have further up! 
    794     private String getJavascript(double ratio, String doc_id, int leg_num) 
    795     { 
    796     String javascript = "\n<script>\nfunction imgClickHandler (evt, img, num) {\n\tif (window.event){\n\t\tvar chooserString = 'placeChooserImage' + '```' + window.event.offsetX + '`' + window.event.offsetY\n\t\tmywindow = window.open(chooserString,'Choose','width=600, height=500, scrollbars=yes, resizable=yes, toolbar=no, location=no, status=yes, menubar=no');\n\t\t//alert(window.event.offsetX + ':' + window.event.offsetY + ':' + num);\n\t}\n\telse if (evt.target) {\n\t\tvar coords = {x: 0, y: 0 };\n\t\tvar el = evt.target;\n\t\tdo {\n\t\t\tcoords.x += el.offsetLeft;\n\t\t\tcoords.y += el.offsetTop;\n\t\t}\n\t\twhile ((el = el.offsetParent));\n\t\tvar offsetX = evt.clientX - coords.x;\n\t\tvar offsetY = evt.clientY - coords.y;\n\t\talert(offsetX + ':' + offsetY + ':' + num);\n\t}\n}\nfunction leapTo (link)\n{\n\tvar new_url=link;\n\tif (  (new_url != \"\")  &&  (new_url != null)  ) \n\t\twindow.location=new_url;\n\telse \n\t\talert(\"You must make a selection.\");\n}\nfunction jumpTo (front,link,back)\n{\n\tvar new_url=front+link+back;\n\tif (  (new_url != \"\")  &&  (new_url != null)  ) \n\t\twindow.location=new_url;\n\telse \n\t\talert(\"You must make a selection.\");\n}// Deactivate Cloaking -->\n</script>"; 
    797  
    798     String radioButtons = "\n<center><FORM>"; 
    799     if(ratio != 0.4) 
    800         radioButtons = radioButtons + "\n\t<INPUT TYPE=\"radio\" NAME=\"buttons1\" onClick=\"leapTo('zoomhead"+doc_id+"`0.4')\">40%"; 
    801     if(ratio != 0.5) 
    802         radioButtons = radioButtons + "\n\t<INPUT TYPE=\"radio\" NAME=\"buttons1\" onClick=\"leapTo('zoomhead"+doc_id+"`0.5')\">50%"; 
    803     if(ratio != 0.6) 
    804         radioButtons = radioButtons + "\n\t<INPUT TYPE=\"radio\" NAME=\"buttons1\" onClick=\"leapTo('zoomhead"+doc_id+"`0.6')\">60%"; 
    805     if(ratio != 0.7) 
    806         radioButtons = radioButtons + "\n\t<INPUT TYPE=\"radio\" NAME=\"buttons1\" onClick=\"leapTo('zoomhead"+doc_id+"`0.7')\">70%"; 
    807     if(ratio != 0.8) 
    808         radioButtons = radioButtons + "\n\t<INPUT TYPE=\"radio\" NAME=\"buttons1\" onClick=\"leapTo('zoomhead"+doc_id+"`0.8')\">80%"; 
    809     if(ratio != 0.9) 
    810         radioButtons = radioButtons + "\n\t<INPUT TYPE=\"radio\" NAME=\"buttons1\" onClick=\"leapTo('zoomhead"+doc_id+"`0.9')\">90%"; 
    811     if(ratio != 1.0) 
    812         radioButtons = radioButtons + "\n\t<INPUT TYPE=\"radio\" NAME=\"buttons1\" onClick=\"leapTo('zoomhead"+doc_id+"`1.0')\">100%"; 
    813     radioButtons = radioButtons + "\n</FORM></center>"; 
    814  
    815     leg_num = leg_num+1; 
    816  
    817     String doc_link = "?a=d&c="+this.cluster_name+"&dt=map&d="+doc_id+"`"+ratio+"`"+leg_num+"`"; 
    818  
    819     StringBuffer dropDownBox = new StringBuffer(); 
    820  
    821     dropDownBox.append("Add Locations Of Type: <form name=\"myForm\"><select name=\"s1index\" onChange=\"jumpTo('"); 
    822     dropDownBox.append(doc_link); 
    823     dropDownBox.append("',document.myForm.s1index.options[document.myForm.s1index.selectedIndex].value,'')\">\n"); 
    824  
    825     for (int i=0; i<this.index_name_list.size(); i++) { 
    826         String name = this.index_name_list.get(i); 
    827         dropDownBox.append("<option value=\""); 
    828         dropDownBox.append(name); 
    829         dropDownBox.append("\">"); 
    830         String display = this.index_display_list.get(i); 
    831         dropDownBox.append(display); 
    832         dropDownBox.append("\n"); 
    833     } 
    834     // for each option, Malcolm had onClick=\"leapTo('"+doc_link+name+"')\" - dont seem to need this 
    835     dropDownBox.append("</select></form>\n"); 
    836  
    837     return javascript + radioButtons + dropDownBox; 
    838     } 
    839940}