Searching Intrinsic ALI Properties Using the PRC

There’s a problem with the IDK PRC API for search that’s tripped up users in the dev2dev forums and that stymied me for the first time today while coding up a custom search application for one of our customers.

The problem is that there’s a hardcoded limitation in the IDK that prevents you from calling PortalField.forID if the passed in object ID is less than 100. This prevents you from searching on some really useful properties, including e-mail address! For the life of me, I can’t figure out why this limitation was imposed.

The good news is that I found a workaround. It involves a quick two-file IDK patch that entails subclassing two classes. The only catch is that you need to put the child classes in the same package as the IDK (because the parent classes have package-private constructors).

Here’s the source code that does the trick.

com.plumtree.remote.prc.search.IntrinsicPortalField.java:

package com.plumtree.remote.prc.search;

import com.plumtree.remote.prc.search.PortalField;
import com.plumtree.remote.prc.search.xp.*;

public class IntrinsicPortalField extends PortalField {
  private IntrinsicPortalField(IntrinsicXPPortalField xpField) {
    super(xpField);
  }

  public static final IntrinsicPortalField EMAIL_ADDRESS;

  static {
    EMAIL_ADDRESS = new IntrinsicPortalField(IntrinsicXPPortalField.forID(26));
  }
}

com.plumtree.remote.prc.search.xp.IntrinsicXPPortalField.java:

package com.plumtree.remote.prc.search.xp;

import com.plumtree.openfoundation.util.XPIllegalArgumentException;

public class IntrinsicXPPortalField extends XPPortalField {

  private IntrinsicXPPortalField(String name, boolean isSearchable, boolean isRetrievable) {
    super(name, isSearchable, isRetrievable);
  }

  public static IntrinsicXPPortalField forID(int propertyId) throws XPIllegalArgumentException {
    return new IntrinsicXPPortalField("ptportal.propertyid." + propertyId, true, true);
  }
}

I used e-mail address (ID = 26) as an example, but you can put any properties in there that you want. Then, when you’re setting up your search filter, just use IntrinsicPortalField instead of PortalField. For example:

IFilterClause filter = searchFactory.createOrFilterClause();
filter.addStatement(IntrinsicPortalField.EMAIL_ADDRESS, Operator.Contains, searchQuery);

Since IntrinsicPortalField is a subclass of PortalField, the PRC has no problem with it. I’ve tested this with e-mail address and it works flawlessly. I’m sure other properties will work perfectly well too.

Enjoy!

Comments

Comments are listed in date ascending order (oldest first)

  • Thank you, Chris 🙂 Now that Chris has kindly posted a workaround, any possibility of having this put into an IDK hotfix?

    Posted by: ewwhitley on August 27, 2006 at 2:39 PM

  • I second Eric’s opinion. Can you guys just remove the artificial restriction of 100 from the IDK in the next release? Seems to work fine without it and it would obviate the need for my silly patch.

    Posted by: bucchere on August 30, 2006 at 2:31 PM

  • Here is an e-mail I received from a person who attempted to use my patch:

     

    I found your blog because I am having the same problem you describe with searching Intrinsic properties. However, I am now having trouble actually “patching” the IDK. How exactly would I go about repackaging everything with these new java files included? Thank you very much for your time and help.

    Here was my response:

    Thanks for your note. Assuming that you’re building a Java web application, all you need to do is compile the patch along with all your other application code. You can put the class files for the patch in WEB-INF/classes or you can make a jar (e.g. myapp.jar) and put the class files for the IDK patch there and then drop the jar in WEB-INF/lib. You can then put everything into a .war or .ear (or not).

    The magic of the Java classloader is that all the .class files in WEB-INF/classes and all your .class files inside jars in WEB-INF/lib all end up loaded into the same memory. That means that if you have two class files in two different jars, but they’re both in the com.plumtree.remote.portlet package (meaning you have the line package com.plumtree.remote.portlet; at the top of your source files and your .java files live in com/plumtree/remote/portlet), then they’ll act like they’re in the same package. This means that you’ll have access to all package private member methods, which the patch needs in order to compile.

    Posted by: bucchere on August 30, 2006 at 7:23 PM

  • Hi mate, I think this is very helpfull but I was wondering where can I find corresponding ID’s for all standart and custom user properties, when I’m using

    forID(26) method? Thanks in advance!

    Posted by: ggeorgiev on September 19, 2006 at 1:16 AM

  • This gets you the standard (intrinsic) ones:
    select objectid, name from plumdbuser.ptproperties order by objectid where objectid < 200;
    1 Name
    2 Description
    3 Object Created
    4 Object Last Modified
    5 Open Document URL
    6 Content Type ID
    7 Plumtree Document Image UUID
    8 Content Language
    9 Content Tag
    26 Email Address
    50 Full Text Content
    60 Document Submit Content Source
    61 Document Upload Repository Server
    62 Document Upload DocID
    71 Related Communities
    72 Related Folders
    73 Related Portlets
    74 Related Experts
    75 Related Content Managers
    80 Snapshot Query Reference
    101 Keywords
    102 Subject
    103 Author
    104 Created
    105 Document Title
    106 URL
    107 Category
    111 Comments
    112 Modified
    152 Phone Number
    153 Title
    154 Department
    155 Manager
    156 Company
    157 Address
    158 Postal Code
    159 State or Province
    160 Country
    161 Employee ID
    162 City
    163 Address 2
    

    For the custom ones, change the where clause to >= 200.

    Posted by: bucchere on September 23, 2006 at 6:53 PM

6 Replies to “Searching Intrinsic ALI Properties Using the PRC”

  1. Just use firebug, tamper, or some other tool that let's you inspect the contents of a form post when you upload a document through the portal UI. Then just reverse engineer the form post. Or you can contract with BDG and we'll build it for you. 🙂

  2. "I just collected those values from a web form " that is what I am doing.

    "then posted them to the portal's existing doc upload endpoint" Not seeing how to post the doc without the api at this point and how you are setting doc properties.

  3. I built something like that many years ago for Columbia University. I just collected those values from a web form that I created and then posted them to the portal's existing doc upload endpoint. No need to use any APIs; you just reverse-engineer the form post. Does that make sense?

  4. Custom uploader….provide a few fields for user to fill out and on upload (.save) to KD, apply the field values the user chose to the properties of the doc you are saving. If the user types a Description, set that property on upload and not allow the portal to get it from the physical doc metadata.

Leave a Reply