Changeset 25427


Ignore:
Timestamp:
2012-04-19T15:34:37+12:00 (12 years ago)
Author:
sjm84
Message:

Reformatting this file ahead of some changes

File:
1 edited

Legend:

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

    r24393 r25427  
    3131// XML classes
    3232import org.w3c.dom.Document;
    33 import org.w3c.dom.Element; 
     33import org.w3c.dom.Element;
    3434import org.w3c.dom.NodeList;
    3535
     
    4747import org.apache.commons.lang3.*;
    4848
    49 /** Implements the generic retrieval and classifier services for GS2
    50  * collections.
    51  *
     49/**
     50 * Implements the generic retrieval and classifier services for GS2 collections.
     51 * 
    5252 * @author Katherine Don
    5353 * @author Michael Dewsnip
    5454 */
    5555
    56 public abstract class AbstractGS2DocumentRetrieve
    57     extends AbstractDocumentRetrieve {
    58 
    59       static Logger logger = Logger.getLogger(org.greenstone.gsdl3.service.AbstractGS2DocumentRetrieve.class.getName());
    60 
    61     //    protected static final String EXTLINK_PARAM = "ext"; here or in base??   
    62     protected String index_stem = null;
    63 
    64     protected SimpleCollectionDatabase coll_db = null;
    65 
    66 
    67     /** constructor */
    68     protected AbstractGS2DocumentRetrieve()
    69     {
    70     this.macro_resolver = new GS2MacroResolver();
    71     }
    72 
    73     public void cleanUp() {
    74         super.cleanUp();
    75         this.coll_db.closeDatabase();
    76     }
    77     /** configure this service */
    78     public boolean configure(Element info, Element extra_info)
    79     {
    80     if (!super.configure(info, extra_info)){
    81         return false;
    82     }
    83    
    84     logger.info("Configuring AbstractGS2DocumentRetrieve...");
    85     //this.config_info = info;
    86    
    87     // the index stem is either specified in the config file or is  the collection name
    88     Element index_stem_elem = (Element) GSXML.getChildByTagName(info, GSXML.INDEX_STEM_ELEM);
    89     if (index_stem_elem != null) {
    90         this.index_stem = index_stem_elem.getAttribute(GSXML.NAME_ATT);
    91     }
    92     if (this.index_stem == null || this.index_stem.equals("")) {
    93         logger.error("AbstractGS2DocumentRetrieve.configure(): indexStem element not found, stem will default to collection name");
    94         this.index_stem = this.cluster_name;
    95     }
    96 
    97     // find out what kind of database we have
    98     Element database_type_elem = (Element) GSXML.getChildByTagName(info, GSXML.DATABASE_TYPE_ELEM);
    99     String database_type = null;
    100     if (database_type_elem != null) {
    101       database_type = database_type_elem.getAttribute(GSXML.NAME_ATT);
    102     }
    103     if (database_type == null || database_type.equals("")) {
    104       database_type = "gdbm"; // the default
    105     }
    106     coll_db = new SimpleCollectionDatabase(database_type);
    107     if (!coll_db.databaseOK()) {
    108       logger.error("Couldn't create the collection database of type "+database_type);
    109       return false;
    110     }
    111    
    112     // Open database for querying
    113     String coll_db_file = GSFile.collectionDatabaseFile(this.site_home, this.cluster_name, this.index_stem, database_type);
    114     if (!this.coll_db.openDatabase(coll_db_file, SimpleCollectionDatabase.READ)) {
    115         logger.error("Could not open collection database!");
    116         return false;
    117     }
    118 
    119     // we need to set the database for our GS2 macro resolver
    120     GS2MacroResolver gs2_macro_resolver = (GS2MacroResolver)this.macro_resolver;
    121     gs2_macro_resolver.setDB(this.coll_db);
    122 
    123     return true;
    124     }
    125 
    126     /** if id ends in .fc, .pc etc, then translate it to the correct id */
    127     protected String translateId(String node_id) {
    128     return OID.translateOID(this.coll_db, node_id); //return this.coll_db.translateOID(node_id);
    129     }
    130    
    131     /** if an id is not a greenstone id (an external id) then translate
    132     it to a greenstone one*/
    133     protected String translateExternalId(String node_id){
    134     return this.coll_db.externalId2OID(node_id);
    135     }
    136 
    137     /** returns the id of the root node of the document containing node node_id. . may be the same as node_id */
    138     protected String getRootId(String node_id) {
    139     return OID.getTop(node_id);
    140     }
    141     /** returns a list of the child ids in order, null if no children */
    142     protected ArrayList getChildrenIds(String node_id) {
    143     DBInfo info = this.coll_db.getInfo(node_id);
    144     if (info == null) {
    145         return null;
    146     }
    147 
    148     String contains = info.getInfo("contains");
    149     if (contains.equals("")) {
    150         return null;
    151     }
    152     ArrayList children = new ArrayList();
    153     StringTokenizer st = new StringTokenizer(contains, ";");
    154     while (st.hasMoreTokens()) {
    155         String child_id = StringUtils.replace(st.nextToken(), "\"", node_id);
    156         children.add(child_id);
    157     }
    158     return children;
    159 
    160     }
    161     /** returns the node id of the parent node, null if no parent */
    162     protected String getParentId(String node_id){
    163     String parent = OID.getParent(node_id);
    164     if (parent.equals(node_id)) {
    165         return null;
    166     }
    167     return parent;
    168     }
    169 
    170     /** get the metadata for the classifier node node_id
    171      * returns a metadataList element:
    172      * <metadataList><metadata name="xxx">value</metadata></metadataList>
    173      */
    174     // assumes only one value per metadata
    175     protected Element getMetadataList(String node_id, boolean all_metadata,
    176                       ArrayList metadata_names) 
    177     throws GSException {
    178     Element metadata_list = this.doc.createElement(GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
    179     DBInfo info = this.coll_db.getInfo(node_id);
    180     if (info == null) {
    181         return null;
    182     }
    183     String lang = "en"; // why do we need this??
    184     if (all_metadata) {
    185         // return everything out of the database
    186         Set keys = info.getKeys();
    187         Iterator it = keys.iterator();
    188         while(it.hasNext()) {
    189         String key = (String)it.next();
    190         //String value = info.getInfo(key);
    191         Vector values = info.getMultiInfo(key);
    192         for(int i=0; i<values.size(); i++) {
    193             GSXML.addMetadata(this.doc, metadata_list, key, this.macro_resolver.resolve((String)values.elementAt(i), lang, MacroResolver.SCOPE_META, node_id));
    194         }
    195         }
    196        
    197     } else {
    198         for (int i=0; i<metadata_names.size(); i++) {
    199                 String meta_name = (String) metadata_names.get(i);
    200         String value = getMetadata(node_id, info, meta_name, lang);
    201         GSXML.addMetadata(this.doc, metadata_list, meta_name, value);
    202         }
    203     }
    204     return metadata_list;
    205     }
    206 
    207     /** returns the structural information asked for.
    208      * info_type may be one of
    209      * INFO_NUM_SIBS, INFO_NUM_CHILDREN, INFO_SIB_POS
    210      */
    211     protected String getStructureInfo(String doc_id, String info_type) {
    212     String value="";
    213     if (info_type.equals(INFO_NUM_SIBS)) {
    214         String parent_id = OID.getParent(doc_id);
    215         if (parent_id.equals(doc_id)) {
    216         value="0";
    217         } else {
    218         value = String.valueOf(getNumChildren(parent_id));
    219         }
    220         return value;
    221     }
    222    
    223     if (info_type.equals(INFO_NUM_CHILDREN)) {
    224         return String.valueOf(getNumChildren(doc_id));
    225     }
    226 
    227    
    228     if (info_type.equals(INFO_SIB_POS)) {
    229         String parent_id = OID.getParent(doc_id);
    230         if (parent_id.equals(doc_id)) {
    231         return "-1";
    232         }
    233        
    234         DBInfo info = this.coll_db.getInfo(parent_id);
    235         if (info==null) {
    236         return "-1";
    237         }
    238        
    239         String contains = info.getInfo("contains");
    240         contains = StringUtils.replace(contains, "\"", parent_id);
    241         String [] children = contains.split(";");
    242         for (int i=0;i<children.length;i++) {
    243         String child_id = children[i];
    244         if (child_id.equals(doc_id)) {
    245             return String.valueOf(i+1); // make it from 1 to length
    246                
    247         }
    248         }
    249        
    250         return "-1";
    251     } else {
    252         return null;
    253     }
    254 
    255     }
    256 
    257     protected int getNumChildren(String node_id) {
    258     DBInfo info = this.coll_db.getInfo(node_id);
    259     if (info == null) {
    260         return 0;
    261     }
    262     String contains = info.getInfo("contains");
    263     if (contains.equals("")) {
    264         return 0;
    265     }
    266     String [] children = contains.split(";");
    267     return children.length;
    268     }
    269    
    270     /** returns the document type of the doc that the specified node
    271     belongs to. should be one of
    272     GSXML.DOC_TYPE_SIMPLE,
    273     GSXML.DOC_TYPE_PAGED,
    274     GSXML.DOC_TYPE_HIERARCHY
    275     */
    276     protected String getDocType(String node_id) {
    277     DBInfo info = this.coll_db.getInfo(node_id);
    278     if (info == null) {
    279         return GSXML.DOC_TYPE_SIMPLE;
    280     }
    281     String doc_type = info.getInfo("doctype");
    282     if (!doc_type.equals("")&&!doc_type.equals("doc")) {
    283         return doc_type;
    284     }
    285 
    286     String top_id = OID.getTop(node_id);
    287     boolean is_top = (top_id.equals(node_id) ? true : false);
    288    
    289     String children = info.getInfo("contains");
    290     boolean is_leaf = (children.equals("") ? true : false);
    291 
    292     if (is_top && is_leaf) { // a single section document
    293         return GSXML.DOC_TYPE_SIMPLE;
    294     }
    295 
    296     // now we just check the top node
    297     if (!is_top) { // we need to look at the top info
    298         info = this.coll_db.getInfo(top_id);
    299     }
    300     if (info == null) {
    301         return GSXML.DOC_TYPE_HIERARCHY;
    302     }
    303  
    304     String childtype = info.getInfo("childtype");
    305     if (childtype.equals("Paged")) {
    306         return GSXML.DOC_TYPE_PAGED;
    307     }
    308     return GSXML.DOC_TYPE_HIERARCHY;
    309     }
    310 
    311     /** returns the content of a node
    312      * should return a nodeContent element:
    313      * <nodeContent>text content or other elements</nodeContent>
    314      */
    315     abstract protected Element getNodeContent(String doc_id, String lang) throws GSException;
    316 
    317     protected String getMetadata(String node_id, DBInfo info,
    318                  String metadata, String lang) {
    319     boolean multiple = false;
    320     String relation = "";
    321     String separator = ", ";
    322     int pos = metadata.indexOf(GSConstants.META_RELATION_SEP);
    323     if (pos ==-1) {
    324               Vector values = info.getMultiInfo(metadata);       
    325           if (values !=null){     
    326           // just a plain meta entry eg dc.Title
    327           StringBuffer result = new StringBuffer();
    328           boolean first = true;
    329           for (int i=0; i<values.size(); i++) {
    330               if (first) {
    331               first = false;
    332               } else {
    333               result.append(separator);
    334               }
    335               result.append(this.macro_resolver.resolve((String)values.elementAt(i), lang, MacroResolver.SCOPE_META, node_id));
    336           }
    337                    return result.toString();
    338           }
    339           else{
    340                 String result  = info.getInfo(metadata);
    341                 return this.macro_resolver.resolve(result, lang, MacroResolver.SCOPE_META, node_id);
    342           }
    343     }
    344 
    345     String temp = metadata.substring(0, pos);
    346     metadata = metadata.substring(pos+1);
    347     // check for all on the front
    348     if (temp.equals("all")) {
    349         multiple=true;     
    350         pos = metadata.indexOf(GSConstants.META_RELATION_SEP);
    351         if (pos ==-1) {
    352         temp = "";
    353         } else {
    354         temp = metadata.substring(0, pos);
    355         metadata = metadata.substring(pos+1);
    356         }
    357     }
    358    
    359     // now check for relational info
    360     if (temp.equals("parent") || temp.equals("root") || temp.equals( "ancestors")) { // "current" "siblings" "children" "descendants"
    361         relation = temp;
    362         pos = metadata.indexOf(GSConstants.META_RELATION_SEP);
    363         if (pos == -1) {
    364         temp = "";
    365         } else {
    366         temp = metadata.substring(0, pos);
    367         metadata = metadata.substring(pos+1);
    368         }
    369     }
    370    
    371     // now look for separator info
    372     if (temp.startsWith(GSConstants.META_SEPARATOR_SEP) && temp.endsWith(GSConstants.META_SEPARATOR_SEP)) {
    373         separator = temp.substring(1, temp.length()-1);
    374        
    375     }
    376    
    377     String relation_id = node_id;
    378     if (relation.equals("parent") || relation.equals("ancestors")) {
    379         relation_id = OID.getParent(node_id);
    380         // parent or ancestor does not include self
    381         if (relation_id.equals(node_id)){
    382         return "";
    383         }
    384     } else if (relation.equals("root")) {
    385         relation_id = OID.getTop(node_id);
    386     }
    387    
    388     // now we either have a single node, or we have ancestors   
    389     DBInfo relation_info;
    390     if (relation_id.equals(node_id)) {
    391         relation_info = info;
    392     } else {
    393         relation_info = this.coll_db.getInfo(relation_id);
    394     }
    395     if (relation_info == null) {
    396         return "";
    397     }
    398 
    399     StringBuffer result = new StringBuffer();
    400 
    401     if (!multiple) {
    402         result.append(this.macro_resolver.resolve(relation_info.getInfo(metadata), lang, MacroResolver.SCOPE_META, relation_id));
    403     } else {
    404         // we have multiple meta
    405         Vector values = relation_info.getMultiInfo(metadata);
    406         if (values != null) {
    407         boolean first = true;
    408         for (int i=0; i<values.size(); i++) {
    409             if (first) {
    410             first = false;
    411             } else {
    412             result.append(separator);
    413             }
    414             result.append(this.macro_resolver.resolve((String)values.elementAt(i), lang, MacroResolver.SCOPE_META, relation_id));
    415         }
    416         }
    417           logger.info(result);
    418     }
    419     // if not ancestors, then this is all we do
    420     if (!relation.equals("ancestors")) {
    421         return result.toString();
    422     }
    423    
    424     // now do the ancestors
    425     String current_id = relation_id;
    426     relation_id = OID.getParent(current_id);
    427     while (!relation_id.equals(current_id)) {
    428         relation_info = this.coll_db.getInfo(relation_id);
    429         if (relation_info == null) return result.toString();
    430         if (!multiple) {
    431         result.insert(0, separator);
    432         result.insert(0, this.macro_resolver.resolve(relation_info.getInfo(metadata), lang, MacroResolver.SCOPE_META, relation_id));
    433         } else {
    434         Vector values = relation_info.getMultiInfo(metadata);
    435         if (values != null) {
    436             for (int i=values.size()-1; i>=0; i--) {
    437             result.insert(0, separator);
    438             result.insert(0, this.macro_resolver.resolve((String)values.elementAt(i), lang, MacroResolver.SCOPE_META, relation_id));
    439             }
    440         }
    441        
    442         }
    443         current_id = relation_id;
    444         relation_id = OID.getParent(current_id);
    445     }
    446     return result.toString();
    447     }
    448    
    449 
    450     /** needs to get info from collection database - if the calling code gets it already it may pay to pass it in instead */
    451     protected String resolveTextMacros(String doc_content, String doc_id, String lang)
    452     {
    453     // resolve any collection specific macros
    454     doc_content = macro_resolver.resolve(doc_content, lang, MacroResolver.SCOPE_TEXT, doc_id);
    455     return doc_content;
    456     }
    457 
    458     protected Element getInfo(String doc_id, String info_type) {
    459 
    460     String value="";
    461     if (info_type.equals(INFO_NUM_SIBS)) {
    462         String parent_id = OID.getParent(doc_id);
    463         if (parent_id.equals(doc_id)) {
    464         value="0";
    465         } else {
    466         value = String.valueOf(getNumChildren(parent_id));
    467         }
    468     } else if (info_type.equals(INFO_NUM_CHILDREN)) {
    469         value = String.valueOf(getNumChildren(doc_id));
    470     } else if (info_type.equals(INFO_SIB_POS)) {
    471         String parent_id = OID.getParent(doc_id);
    472         if (parent_id.equals(doc_id)) {
    473         value="-1";
    474         } else {
    475         DBInfo info = this.coll_db.getInfo(parent_id);
    476         if (info==null) {
    477             value ="-1";
    478         } else {
    479             String contains = info.getInfo("contains");
    480             contains = StringUtils.replace(contains, "\"", parent_id);
    481             String [] children = contains.split(";");
    482             for (int i=0;i<children.length;i++) {
    483             String child_id = children[i];
    484             if (child_id.equals(doc_id)) {
    485                 value = String.valueOf(i+1); // make it from 1 to length
    486                 break;
    487             }
    488             }
    489         }
    490         }
    491     } else {
    492         return null;
    493     }
    494     Element info_elem = this.doc.createElement("info");
    495     info_elem.setAttribute(GSXML.NAME_ATT, info_type);
    496     info_elem.setAttribute(GSXML.VALUE_ATT, value);
    497     return info_elem;
    498     }
    499 
    500     protected String getHrefOID(String href_url){
    501         return this.coll_db.docnum2OID(href_url);
    502     }
    503 
    504 }   
     56public abstract class AbstractGS2DocumentRetrieve extends AbstractDocumentRetrieve
     57{
     58
     59    static Logger logger = Logger.getLogger(org.greenstone.gsdl3.service.AbstractGS2DocumentRetrieve.class.getName());
     60
     61    //    protected static final String EXTLINK_PARAM = "ext"; here or in base??   
     62    protected String index_stem = null;
     63
     64    protected SimpleCollectionDatabase coll_db = null;
     65
     66    /** constructor */
     67    protected AbstractGS2DocumentRetrieve()
     68    {
     69        this.macro_resolver = new GS2MacroResolver();
     70    }
     71
     72    public void cleanUp()
     73    {
     74        super.cleanUp();
     75        this.coll_db.closeDatabase();
     76    }
     77
     78    /** configure this service */
     79    public boolean configure(Element info, Element extra_info)
     80    {
     81        if (!super.configure(info, extra_info))
     82        {
     83            return false;
     84        }
     85
     86        logger.info("Configuring AbstractGS2DocumentRetrieve...");
     87        //this.config_info = info;
     88
     89        // the index stem is either specified in the config file or is  the collection name
     90        Element index_stem_elem = (Element) GSXML.getChildByTagName(info, GSXML.INDEX_STEM_ELEM);
     91        if (index_stem_elem != null)
     92        {
     93            this.index_stem = index_stem_elem.getAttribute(GSXML.NAME_ATT);
     94        }
     95        if (this.index_stem == null || this.index_stem.equals(""))
     96        {
     97            logger.error("AbstractGS2DocumentRetrieve.configure(): indexStem element not found, stem will default to collection name");
     98            this.index_stem = this.cluster_name;
     99        }
     100
     101        // find out what kind of database we have
     102        Element database_type_elem = (Element) GSXML.getChildByTagName(info, GSXML.DATABASE_TYPE_ELEM);
     103        String database_type = null;
     104        if (database_type_elem != null)
     105        {
     106            database_type = database_type_elem.getAttribute(GSXML.NAME_ATT);
     107        }
     108        if (database_type == null || database_type.equals(""))
     109        {
     110            database_type = "gdbm"; // the default
     111        }
     112        coll_db = new SimpleCollectionDatabase(database_type);
     113        if (!coll_db.databaseOK())
     114        {
     115            logger.error("Couldn't create the collection database of type " + database_type);
     116            return false;
     117        }
     118
     119        // Open database for querying
     120        String coll_db_file = GSFile.collectionDatabaseFile(this.site_home, this.cluster_name, this.index_stem, database_type);
     121        if (!this.coll_db.openDatabase(coll_db_file, SimpleCollectionDatabase.READ))
     122        {
     123            logger.error("Could not open collection database!");
     124            return false;
     125        }
     126
     127        // we need to set the database for our GS2 macro resolver
     128        GS2MacroResolver gs2_macro_resolver = (GS2MacroResolver) this.macro_resolver;
     129        gs2_macro_resolver.setDB(this.coll_db);
     130
     131        return true;
     132    }
     133
     134    /** if id ends in .fc, .pc etc, then translate it to the correct id */
     135    protected String translateId(String node_id)
     136    {
     137        return OID.translateOID(this.coll_db, node_id); //return this.coll_db.translateOID(node_id);
     138    }
     139
     140    /**
     141     * if an id is not a greenstone id (an external id) then translate it to a
     142     * greenstone one
     143     */
     144    protected String translateExternalId(String node_id)
     145    {
     146        return this.coll_db.externalId2OID(node_id);
     147    }
     148
     149    /**
     150     * returns the id of the root node of the document containing node node_id.
     151     * . may be the same as node_id
     152     */
     153    protected String getRootId(String node_id)
     154    {
     155        return OID.getTop(node_id);
     156    }
     157
     158    /** returns a list of the child ids in order, null if no children */
     159    protected ArrayList getChildrenIds(String node_id)
     160    {
     161        DBInfo info = this.coll_db.getInfo(node_id);
     162        if (info == null)
     163        {
     164            return null;
     165        }
     166
     167        String contains = info.getInfo("contains");
     168        if (contains.equals(""))
     169        {
     170            return null;
     171        }
     172        ArrayList children = new ArrayList();
     173        StringTokenizer st = new StringTokenizer(contains, ";");
     174        while (st.hasMoreTokens())
     175        {
     176            String child_id = StringUtils.replace(st.nextToken(), "\"", node_id);
     177            children.add(child_id);
     178        }
     179        return children;
     180
     181    }
     182
     183    /** returns the node id of the parent node, null if no parent */
     184    protected String getParentId(String node_id)
     185    {
     186        String parent = OID.getParent(node_id);
     187        if (parent.equals(node_id))
     188        {
     189            return null;
     190        }
     191        return parent;
     192    }
     193
     194    /**
     195     * get the metadata for the classifier node node_id returns a metadataList
     196     * element: <metadataList><metadata
     197     * name="xxx">value</metadata></metadataList>
     198     */
     199    // assumes only one value per metadata
     200    protected Element getMetadataList(String node_id, boolean all_metadata, ArrayList metadata_names) throws GSException
     201    {
     202        Element metadata_list = this.doc.createElement(GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
     203        DBInfo info = this.coll_db.getInfo(node_id);
     204        if (info == null)
     205        {
     206            return null;
     207        }
     208        String lang = "en"; // why do we need this??
     209        if (all_metadata)
     210        {
     211            // return everything out of the database
     212            Set keys = info.getKeys();
     213            Iterator it = keys.iterator();
     214            while (it.hasNext())
     215            {
     216                String key = (String) it.next();
     217                //String value = info.getInfo(key);
     218                Vector values = info.getMultiInfo(key);
     219                for (int i = 0; i < values.size(); i++)
     220                {
     221                    GSXML.addMetadata(this.doc, metadata_list, key, this.macro_resolver.resolve((String) values.elementAt(i), lang, MacroResolver.SCOPE_META, node_id));
     222                }
     223            }
     224
     225        }
     226        else
     227        {
     228            for (int i = 0; i < metadata_names.size(); i++)
     229            {
     230                String meta_name = (String) metadata_names.get(i);
     231                String value = getMetadata(node_id, info, meta_name, lang);
     232                GSXML.addMetadata(this.doc, metadata_list, meta_name, value);
     233            }
     234        }
     235        return metadata_list;
     236    }
     237
     238    /**
     239     * returns the structural information asked for. info_type may be one of
     240     * INFO_NUM_SIBS, INFO_NUM_CHILDREN, INFO_SIB_POS
     241     */
     242    protected String getStructureInfo(String doc_id, String info_type)
     243    {
     244        String value = "";
     245        if (info_type.equals(INFO_NUM_SIBS))
     246        {
     247            String parent_id = OID.getParent(doc_id);
     248            if (parent_id.equals(doc_id))
     249            {
     250                value = "0";
     251            }
     252            else
     253            {
     254                value = String.valueOf(getNumChildren(parent_id));
     255            }
     256            return value;
     257        }
     258
     259        if (info_type.equals(INFO_NUM_CHILDREN))
     260        {
     261            return String.valueOf(getNumChildren(doc_id));
     262        }
     263
     264        if (info_type.equals(INFO_SIB_POS))
     265        {
     266            String parent_id = OID.getParent(doc_id);
     267            if (parent_id.equals(doc_id))
     268            {
     269                return "-1";
     270            }
     271
     272            DBInfo info = this.coll_db.getInfo(parent_id);
     273            if (info == null)
     274            {
     275                return "-1";
     276            }
     277
     278            String contains = info.getInfo("contains");
     279            contains = StringUtils.replace(contains, "\"", parent_id);
     280            String[] children = contains.split(";");
     281            for (int i = 0; i < children.length; i++)
     282            {
     283                String child_id = children[i];
     284                if (child_id.equals(doc_id))
     285                {
     286                    return String.valueOf(i + 1); // make it from 1 to length
     287
     288                }
     289            }
     290
     291            return "-1";
     292        }
     293        else
     294        {
     295            return null;
     296        }
     297
     298    }
     299
     300    protected int getNumChildren(String node_id)
     301    {
     302        DBInfo info = this.coll_db.getInfo(node_id);
     303        if (info == null)
     304        {
     305            return 0;
     306        }
     307        String contains = info.getInfo("contains");
     308        if (contains.equals(""))
     309        {
     310            return 0;
     311        }
     312        String[] children = contains.split(";");
     313        return children.length;
     314    }
     315
     316    /**
     317     * returns the document type of the doc that the specified node belongs to.
     318     * should be one of GSXML.DOC_TYPE_SIMPLE, GSXML.DOC_TYPE_PAGED,
     319     * GSXML.DOC_TYPE_HIERARCHY
     320     */
     321    protected String getDocType(String node_id)
     322    {
     323        DBInfo info = this.coll_db.getInfo(node_id);
     324        if (info == null)
     325        {
     326            return GSXML.DOC_TYPE_SIMPLE;
     327        }
     328        String doc_type = info.getInfo("doctype");
     329        if (!doc_type.equals("") && !doc_type.equals("doc"))
     330        {
     331            return doc_type;
     332        }
     333
     334        String top_id = OID.getTop(node_id);
     335        boolean is_top = (top_id.equals(node_id) ? true : false);
     336
     337        String children = info.getInfo("contains");
     338        boolean is_leaf = (children.equals("") ? true : false);
     339
     340        if (is_top && is_leaf)
     341        { // a single section document
     342            return GSXML.DOC_TYPE_SIMPLE;
     343        }
     344
     345        // now we just check the top node
     346        if (!is_top)
     347        { // we need to look at the top info
     348            info = this.coll_db.getInfo(top_id);
     349        }
     350        if (info == null)
     351        {
     352            return GSXML.DOC_TYPE_HIERARCHY;
     353        }
     354
     355        String childtype = info.getInfo("childtype");
     356        if (childtype.equals("Paged"))
     357        {
     358            return GSXML.DOC_TYPE_PAGED;
     359        }
     360        return GSXML.DOC_TYPE_HIERARCHY;
     361    }
     362
     363    /**
     364     * returns the content of a node should return a nodeContent element:
     365     * <nodeContent>text content or other elements</nodeContent>
     366     */
     367    abstract protected Element getNodeContent(String doc_id, String lang) throws GSException;
     368
     369    protected String getMetadata(String node_id, DBInfo info, String metadata, String lang)
     370    {
     371        boolean multiple = false;
     372        String relation = "";
     373        String separator = ", ";
     374        int pos = metadata.indexOf(GSConstants.META_RELATION_SEP);
     375        if (pos == -1)
     376        {
     377            Vector values = info.getMultiInfo(metadata);
     378            if (values != null)
     379            {
     380                // just a plain meta entry eg dc.Title
     381                StringBuffer result = new StringBuffer();
     382                boolean first = true;
     383                for (int i = 0; i < values.size(); i++)
     384                {
     385                    if (first)
     386                    {
     387                        first = false;
     388                    }
     389                    else
     390                    {
     391                        result.append(separator);
     392                    }
     393                    result.append(this.macro_resolver.resolve((String) values.elementAt(i), lang, MacroResolver.SCOPE_META, node_id));
     394                }
     395                return result.toString();
     396            }
     397            else
     398            {
     399                String result = info.getInfo(metadata);
     400                return this.macro_resolver.resolve(result, lang, MacroResolver.SCOPE_META, node_id);
     401            }
     402        }
     403
     404        String temp = metadata.substring(0, pos);
     405        metadata = metadata.substring(pos + 1);
     406        // check for all on the front
     407        if (temp.equals("all"))
     408        {
     409            multiple = true;
     410            pos = metadata.indexOf(GSConstants.META_RELATION_SEP);
     411            if (pos == -1)
     412            {
     413                temp = "";
     414            }
     415            else
     416            {
     417                temp = metadata.substring(0, pos);
     418                metadata = metadata.substring(pos + 1);
     419            }
     420        }
     421
     422        // now check for relational info
     423        if (temp.equals("parent") || temp.equals("root") || temp.equals("ancestors"))
     424        { // "current" "siblings" "children" "descendants"
     425            relation = temp;
     426            pos = metadata.indexOf(GSConstants.META_RELATION_SEP);
     427            if (pos == -1)
     428            {
     429                temp = "";
     430            }
     431            else
     432            {
     433                temp = metadata.substring(0, pos);
     434                metadata = metadata.substring(pos + 1);
     435            }
     436        }
     437
     438        // now look for separator info
     439        if (temp.startsWith(GSConstants.META_SEPARATOR_SEP) && temp.endsWith(GSConstants.META_SEPARATOR_SEP))
     440        {
     441            separator = temp.substring(1, temp.length() - 1);
     442
     443        }
     444
     445        String relation_id = node_id;
     446        if (relation.equals("parent") || relation.equals("ancestors"))
     447        {
     448            relation_id = OID.getParent(node_id);
     449            // parent or ancestor does not include self
     450            if (relation_id.equals(node_id))
     451            {
     452                return "";
     453            }
     454        }
     455        else if (relation.equals("root"))
     456        {
     457            relation_id = OID.getTop(node_id);
     458        }
     459
     460        // now we either have a single node, or we have ancestors   
     461        DBInfo relation_info;
     462        if (relation_id.equals(node_id))
     463        {
     464            relation_info = info;
     465        }
     466        else
     467        {
     468            relation_info = this.coll_db.getInfo(relation_id);
     469        }
     470        if (relation_info == null)
     471        {
     472            return "";
     473        }
     474
     475        StringBuffer result = new StringBuffer();
     476
     477        if (!multiple)
     478        {
     479            result.append(this.macro_resolver.resolve(relation_info.getInfo(metadata), lang, MacroResolver.SCOPE_META, relation_id));
     480        }
     481        else
     482        {
     483            // we have multiple meta
     484            Vector values = relation_info.getMultiInfo(metadata);
     485            if (values != null)
     486            {
     487                boolean first = true;
     488                for (int i = 0; i < values.size(); i++)
     489                {
     490                    if (first)
     491                    {
     492                        first = false;
     493                    }
     494                    else
     495                    {
     496                        result.append(separator);
     497                    }
     498                    result.append(this.macro_resolver.resolve((String) values.elementAt(i), lang, MacroResolver.SCOPE_META, relation_id));
     499                }
     500            }
     501            logger.info(result);
     502        }
     503        // if not ancestors, then this is all we do
     504        if (!relation.equals("ancestors"))
     505        {
     506            return result.toString();
     507        }
     508
     509        // now do the ancestors
     510        String current_id = relation_id;
     511        relation_id = OID.getParent(current_id);
     512        while (!relation_id.equals(current_id))
     513        {
     514            relation_info = this.coll_db.getInfo(relation_id);
     515            if (relation_info == null)
     516                return result.toString();
     517            if (!multiple)
     518            {
     519                result.insert(0, separator);
     520                result.insert(0, this.macro_resolver.resolve(relation_info.getInfo(metadata), lang, MacroResolver.SCOPE_META, relation_id));
     521            }
     522            else
     523            {
     524                Vector values = relation_info.getMultiInfo(metadata);
     525                if (values != null)
     526                {
     527                    for (int i = values.size() - 1; i >= 0; i--)
     528                    {
     529                        result.insert(0, separator);
     530                        result.insert(0, this.macro_resolver.resolve((String) values.elementAt(i), lang, MacroResolver.SCOPE_META, relation_id));
     531                    }
     532                }
     533
     534            }
     535            current_id = relation_id;
     536            relation_id = OID.getParent(current_id);
     537        }
     538        return result.toString();
     539    }
     540
     541    /**
     542     * needs to get info from collection database - if the calling code gets it
     543     * already it may pay to pass it in instead
     544     */
     545    protected String resolveTextMacros(String doc_content, String doc_id, String lang)
     546    {
     547        // resolve any collection specific macros
     548        doc_content = macro_resolver.resolve(doc_content, lang, MacroResolver.SCOPE_TEXT, doc_id);
     549        return doc_content;
     550    }
     551
     552    protected Element getInfo(String doc_id, String info_type)
     553    {
     554
     555        String value = "";
     556        if (info_type.equals(INFO_NUM_SIBS))
     557        {
     558            String parent_id = OID.getParent(doc_id);
     559            if (parent_id.equals(doc_id))
     560            {
     561                value = "0";
     562            }
     563            else
     564            {
     565                value = String.valueOf(getNumChildren(parent_id));
     566            }
     567        }
     568        else if (info_type.equals(INFO_NUM_CHILDREN))
     569        {
     570            value = String.valueOf(getNumChildren(doc_id));
     571        }
     572        else if (info_type.equals(INFO_SIB_POS))
     573        {
     574            String parent_id = OID.getParent(doc_id);
     575            if (parent_id.equals(doc_id))
     576            {
     577                value = "-1";
     578            }
     579            else
     580            {
     581                DBInfo info = this.coll_db.getInfo(parent_id);
     582                if (info == null)
     583                {
     584                    value = "-1";
     585                }
     586                else
     587                {
     588                    String contains = info.getInfo("contains");
     589                    contains = StringUtils.replace(contains, "\"", parent_id);
     590                    String[] children = contains.split(";");
     591                    for (int i = 0; i < children.length; i++)
     592                    {
     593                        String child_id = children[i];
     594                        if (child_id.equals(doc_id))
     595                        {
     596                            value = String.valueOf(i + 1); // make it from 1 to length
     597                            break;
     598                        }
     599                    }
     600                }
     601            }
     602        }
     603        else
     604        {
     605            return null;
     606        }
     607        Element info_elem = this.doc.createElement("info");
     608        info_elem.setAttribute(GSXML.NAME_ATT, info_type);
     609        info_elem.setAttribute(GSXML.VALUE_ATT, value);
     610        return info_elem;
     611    }
     612
     613    protected String getHrefOID(String href_url)
     614    {
     615        return this.coll_db.docnum2OID(href_url);
     616    }
     617
     618}
Note: See TracChangeset for help on using the changeset viewer.