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?
- 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.
- 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 inWEB-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 inWEB-INF/classes
and all your.class
files inside jars inWEB-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 thecom.plumtree.remote.portlet
package (meaning you have the linepackage com.plumtree.remote.portlet;
at the top of your source files and your.java
files live incom/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.
- 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!
- 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 2For the custom ones, change the where clause to
>= 200
.