001: /*
002: * Copyright 2001 Sun Microsystems, Inc. All rights reserved.
003: * PROPRIETARY/CONFIDENTIAL. Use of this product is subject to license terms.
004: */
005:
006: package com.sun.portal.search.db;
007:
008: import com.sun.portal.search.soif.*;
009: import com.sun.portal.search.util.*;
010: import com.sun.portal.search.rdm.*;
011: import com.sun.portal.log.common.PortalLogger;
012:
013: import java.io.*;
014: import java.util.*;
015: import java.util.logging.Logger;
016: import java.util.logging.Level;
017:
018: /**
019: * The main routine is stamp_rd which calculates rd-last-changed
020: */
021: class RDLastChangedPlugin {
022:
023: /** Load alertable attributes - must be called after schema is loaded, or will have no effect */
024: static public void load_alert_config(RDLastChangedList rdlist,
025: String serverroot) throws Exception {
026: List attrs = new ArrayList();
027: String attr;
028: String alert_str = null;
029: RDMSchema schema = RDMSchema.getSchema("Document"); // XXX hard code
030: if (schema == null) {
031: Logger debugLogger = SearchLogger.getLogger();
032: debugLogger.log(Level.WARNING, "PSSH_CSPSB0062");
033: return;
034: }
035: int n = schema.getNumEntriesInt();
036: for (int i = 0; i < n; i++) {
037: if ((attr = schema.getSOIFAttribute(i)) != null
038: && (alert_str = schema.getIsAlertable(i)) != null
039: && !alert_str.equals("0")) {
040: Logger debugLogger = SearchLogger.getLogger();
041: debugLogger.log(Level.FINE, "PSSH_CSPSB0063", attr);
042: attrs.add(attr);
043: }
044: }
045: rdlist.interest_list = (String[]) attrs
046: .toArray(new String[attrs.size()]);
047: }
048:
049: /**
050: * Calulates rd-last-changed for a new RD.
051: * (nps must not be null)
052: */
053: static public void stamp_rd(RDLastChanged rdlc,
054: RDLastChangedList rdlist, SOIF ops, SOIF ons, SOIF nps,
055: SOIF nns, boolean is_persistent) {
056: String p;
057:
058: if (!rdlc.update_flag) {
059: // XXX probably should always check both N and NP/merged RD
060: if (is_persistent)
061: is_rd_modified(rdlist, rdlc, ops, nps);
062: else
063: is_rd_modified(rdlist, rdlc, ons, nns);
064: }
065:
066: if (rdlc.update_flag) {
067: // save old rd-last-changed (nps might == ops)
068: if (ops != null
069: && (p = ops.getValue("rd-last-changed")) != null) {
070: try {
071: rdlc.old_rdlc = DateParser.parse(p);
072: } catch (Exception ignored) {
073: Logger debugLogger = SearchLogger.getLogger();
074: debugLogger.log(Level.WARNING, "PSSH_CSPSB0064",
075: ops.getURL());
076: }
077: }
078: // set new rd-last-modified
079: rdlc.new_rdlc = new Date();
080: nps.replace("rd-last-changed", rdlc.new_rdlc.toString());
081: }
082: }
083:
084: /**
085: * Compares old and new SOIFs and sets the rdlc update flag
086: * if any of the attrs on the interest list are different.
087: */
088: static protected void is_rd_modified(RDLastChangedList rdlist,
089: RDLastChanged rdlc, SOIF os, SOIF ns) {
090:
091: int j, ix, ox, nx, o_cnt, n_cnt, m_cnt;
092: boolean inclusive = rdlist.inclusive;
093:
094: if (os == ns || rdlist.interest_list == null)
095: return;
096:
097: if (os == null) {
098: /**
099: * XXX not quite right - should still only look at
100: * rdlist attrs, but it is a new RD after all, so I guess it's OK.
101: * Also wrong if it's NP being covered by P.
102: * P only is OK, because that won't get indexed anyway.
103: */
104: rdlc.update_flag = true;
105: return;
106: }
107:
108: // look for differences in the attributes in the interest list
109: for (int i = 0; i < rdlist.interest_list.length; ++i) {
110: String attr = rdlist.interest_list[i];
111: AVPair aold = os.getAVPair(attr);
112: AVPair anew = ns.getAVPair(attr);
113: if (aold == null && anew == null)
114: continue;
115: if (aold == null && anew != null || aold != null
116: && anew == null) {
117: rdlc.update_flag = true;
118: return;
119: }
120: byte[][] bold = aold.getByteValues();
121: byte[][] bnew = anew.getByteValues();
122: if (bold.length != bnew.length) {
123: rdlc.update_flag = true;
124: return;
125: }
126: Arrays.sort(bold, bacomparator);
127: Arrays.sort(bnew, bacomparator);
128: for (int k = 0; k < bold.length; ++k) {
129: if (!Arrays.equals(bold[k], bnew[k])) {
130: rdlc.update_flag = true;
131: return;
132: }
133: }
134: }
135:
136: } // is_rd_modified
137:
138: static Comparator bacomparator = new ByteArrayComparator();
139:
140: }
141:
142: class ByteArrayComparator implements Comparator {
143:
144: public int compare(Object o1, Object o2) {
145:
146: if (o1 == null && o2 == null)
147: return 0;
148: if (o1 == null)
149: return -1;
150: if (o2 == null)
151: return +1;
152:
153: byte[] b1 = (byte[]) o1;
154: byte[] b2 = (byte[]) o2;
155: int i;
156: for (i = 0; i < b1.length && i < b2.length; ++i) {
157: if (b1[i] == b2[i])
158: continue;
159: if (b1[i] < b2[i])
160: return -1;
161: return +1;
162: }
163: if (i < b2.length)
164: return -1;
165: if (i < b1.length)
166: return +1;
167: return 0;
168: }
169:
170: }
|