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.admin;
007:
008: import java.io.*;
009: import java.net.*;
010: import java.util.*;
011: import java.util.logging.Level;
012: import java.util.logging.Logger;
013:
014: import com.iplanet.jato.view.RequestHandlingTiledViewBase;
015: import com.iplanet.jato.view.View;
016: import com.iplanet.jato.view.ViewBean;
017: import com.iplanet.jato.view.ViewBeanBase;
018: import com.iplanet.jato.view.TiledView;
019: import com.iplanet.jato.RequestHandler;
020: import com.iplanet.jato.model.*;
021: import com.iplanet.jato.view.event.DisplayEvent;
022: import com.iplanet.jato.view.event.RequestInvocationEvent;
023: import com.iplanet.jato.view.event.TiledViewRequestInvocationEvent;
024: import com.iplanet.jato.view.event.ChildDisplayEvent;
025: import com.iplanet.jato.view.html.StaticTextField;
026: import com.iplanet.jato.view.html.ListBox;
027: import com.iplanet.jato.view.html.TextField;
028: import com.iplanet.jato.view.html.OptionList;
029: import com.iplanet.jato.view.html.Button;
030: import com.iplanet.jato.view.html.HiddenField;
031: import com.iplanet.jato.util.Encoder;
032:
033: import javax.servlet.http.HttpServletRequest;
034: import javax.servlet.http.HttpServletResponse;
035:
036: import com.sun.portal.search.rdm.*;
037:
038: import com.iplanet.am.console.components.view.html.DynamicGUI;
039: import com.iplanet.am.console.components.view.html.DynamicGUIComp;
040:
041: import com.iplanet.sso.SSOTokenManager;
042: import com.iplanet.sso.SSOToken;
043: import com.iplanet.sso.SSOException;
044: import com.iplanet.sso.SSOTokenID;
045:
046: import com.sun.portal.search.soif.*;
047: import com.sun.portal.search.db.SToken;
048: import com.sun.portal.search.util.SearchConfig;
049: import com.sun.portal.log.common.PortalLogger;
050:
051: import com.iplanet.am.console.components.view.html.IPlanetButton;
052:
053: /**
054: * This view uses model of type AMIndentedListModel to display a tree like
055: * heirarchichal data structure in expanded tree form. So when a tree is
056: * expanded its nodes are displayed as indented rows. The indentation is
057: * relative to the parent node.
058: * Each row has this structure: [checkbox]name[link]
059: * The checkbox and link can be turned on or off. Thus,those nodes which are only
060: * for labeling purpose, can have only the name displayed in the row. This view
061: * uses TiledView of JATO, and hence each row is a tile.
062: * Typicaly, the subclasses will use the link to display the properties
063: * associated with the name, and checkbox may be used for add/delete operations.
064: */
065: public class RDView extends RequestHandlingTiledViewBase implements
066: TiledView, RequestHandler {
067: public static final String RD_AV_SET = "rdAVSet";
068:
069: public static final String FIELD_NAME = "FieldName";
070: public static final String EDITFIELD_NAME = "EditFieldName";
071: public static final String FIELD_CHANGED = "FieldChanged";
072: public static final String FIELD_VALUE = "EditableFieldText";
073: public static final String FIELD_COMBO = "SelectableFieldText";
074: public static final String STATIC_FIELD_VALUE = "FieldText";
075: public static final String TAXBROWSE_BUTTON = "TaxBrowser";
076:
077: public ArrayList urlList = null;/* batch by list of url*/
078: public String queryString = null;/*batch by query */
079: String database = null;
080: String editTimeStamp = null;
081:
082: public SToken st = null;
083:
084: private SOIF s = null;
085: private RDMSchema schema = null;
086: private boolean atClassificationField = false;
087: private HashMap storedMap = null;
088: private ArrayList fieldList = new ArrayList();/*stored editable soif attribute column index*/
089: private boolean isSingleMode = true;
090: public static final String batchFillin = "*****";
091:
092: // Create a Logger for this class
093: private static Logger debugLogger = PortalLogger
094: .getLogger(RDView.class);
095:
096: public RDView(View parent, String name) {
097: super (parent, name);
098: setPrimaryModel((DatasetModel) getDefaultModel());
099: registerChildren();
100: loadSchema();
101: }
102:
103: protected void registerChildren() {
104: registerChild(RD_AV_SET, DynamicGUIComp.class);
105: registerChild(TAXBROWSE_BUTTON, IPlanetButton.class);
106: }
107:
108: protected View createChild(String name) {
109: if (name.equals(RD_AV_SET)) {
110: return new DynamicGUIComp(this , RD_AV_SET, null);
111: } else if (name.equals(TAXBROWSE_BUTTON)) {
112: IPlanetButton btn = new IPlanetButton(this ,
113: TAXBROWSE_BUTTON, "");
114: btn.validate(true);
115: return btn;
116: } else {
117: throw new IllegalArgumentException("Invalid child name: "
118: + name);
119: }
120:
121: }
122:
123: public static ArrayList parseURLSString(String urls) {
124: ArrayList list = new ArrayList();
125: StringTokenizer st = new StringTokenizer(urls, ".");
126: while (st.hasMoreTokens()) {
127: String url = st.nextToken();
128: if (url.trim().length() == 0) {
129: continue;
130: }
131: try {
132: String urlString = new String(
133: Encoder.decodeBase64(url), "UTF-8");
134: debugLogger.log(Level.FINER, "PSSH_CSPSA0096",
135: urlString);
136: list.add(urlString);
137: } catch (Exception e) {
138:
139: }
140: }
141: return list;
142: }
143:
144: /**
145: *
146: *
147: */
148: public void beginDisplay(DisplayEvent event)
149: throws ModelControlException {
150: ViewBean pvb = getParentViewBean();
151: editTimeStamp = (String) pvb
152: .getPageSessionAttribute("editTimeStamp");
153: debugLogger.log(Level.FINER, "PSSH_CSPSA0089", editTimeStamp);
154: if (editTimeStamp == null) {
155: editTimeStamp = getRequestContext().getRequest()
156: .getParameter("editTimeStamp");
157: debugLogger.log(Level.FINER, "PSSH_CSPSA0090",
158: editTimeStamp);
159: if (editTimeStamp != null) {
160: pvb.setPageSessionAttribute("editTimeStamp",
161: editTimeStamp);
162: } else {
163: debugLogger.finer("PSSH_CSPSA0084");
164: }
165: }
166: database = (String) getRequestContext().getRequest()
167: .getSession().getAttribute("database" + editTimeStamp);
168: if (database == null) {
169: database = getRequestContext().getRequest().getParameter(
170: "database");
171: if (database != null) {
172: getRequestContext().getRequest().getSession()
173: .setAttribute("database" + editTimeStamp,
174: database);
175: }
176: }
177: urlList = (ArrayList) pvb.getRequestContext().getRequest()
178: .getSession().getAttribute("urls" + editTimeStamp);
179: if (urlList == null) {
180: String urlsPar = getRequestContext().getRequest()
181: .getParameter("urls");
182: if (urlsPar != null) {
183: urlList = parseURLSString(urlsPar);
184: pvb.getRequestContext().getRequest().getSession()
185: .setAttribute("urls" + editTimeStamp, urlList);
186: }
187: }
188: queryString = (String) pvb.getPageSessionAttribute("query");
189: if (queryString == null) {
190: String queryPar = getRequestContext().getRequest()
191: .getParameter("query");
192: if (queryPar != null) {
193: try {
194: queryString = new String(Encoder
195: .decodeBase64(queryPar), "UTF-8");
196: pvb.setPageSessionAttribute("query", queryString);
197: } catch (Exception e) {
198: }
199: }
200: }
201:
202: isSingleMode = (queryString == null && urlList != null && urlList
203: .size() == 1);
204:
205: if (isSingleMode) {
206: try {
207: RDSearch rdSearch = new RDSearch();
208: ArrayList rds = rdSearch.search(database,
209: (String) urlList.get(0), 5, 1, 1, getSToken());
210: s = (SOIF) rds.get(0);
211: } catch (Exception e) {
212: debugLogger.log(Level.INFO, "PSSH_CSPSA0010", e
213: .getMessage());
214: return;
215: }
216: }
217: int n = schema.getMaxIndex();
218: for (int i = 0; i <= n; i++) {
219: String name = schema.getSOIFAttribute(i);
220: //name might be null if the attribut at that column number has been deleted
221: if (name == null) {
222: continue;
223: }
224: String isEditable = schema.getValue(name,
225: RDM.A_RDM_EDIT_ATTR);
226: if (isSingleMode
227: || (isEditable != null && isEditable
228: .equalsIgnoreCase("1"))) {
229: fieldList.add(name);
230: }
231: }
232:
233: getPrimaryModel().setSize(fieldList.size());
234:
235: storedMap = (HashMap) pvb.getRequestContext().getRequest()
236: .getSession()
237: .getAttribute("DynamicGUI" + editTimeStamp);
238: }
239:
240: public boolean beginTaxonomyBrowseDisplay(ChildDisplayEvent event) {
241: return atClassificationField;
242: }
243:
244: /**
245: * Increments the current tile position to the next available tile position.
246: * This method sets the current row in the model to the current tile index
247: * and builds the dynamic gui component for the attribute in the current
248: * row.
249: *
250: * @return True if successful.
251: * @throws ModelControlException
252: */
253: public boolean nextTile() throws ModelControlException {
254: boolean movedToRow = super .nextTile();
255: int ndx = getTileIndex();
256: CSViewBeanBase pvb = (CSViewBeanBase) getParentViewBean();
257:
258: if (movedToRow) {
259: DynamicGUI dg = null;
260: DynamicGUIComp dgc = (DynamicGUIComp) getChild(RD_AV_SET);
261:
262: // Put row specific logic here
263: String name = (String) fieldList.get(ndx);
264: int sndx = schema.getColumnNumber(name);
265: String type = schema.getDataType(sndx);
266: //None is a required attribute.
267: boolean required = false;
268: int attrType = DynamicGUI.TYPE_SINGLE;
269: int attrSyntax = DynamicGUI.SYNTAX_STRING;
270: setDisplayFieldValue(TAXBROWSE_BUTTON, pvb
271: .getLocalizedString("category.browser.launch"));
272: atClassificationField = name
273: .equalsIgnoreCase("Classification");
274: if (name.equalsIgnoreCase("ReadACL")
275: || name.equalsIgnoreCase("Classification")) {
276: attrType = DynamicGUI.TYPE_LIST;
277: }
278: String label = name;
279: Set values = null;
280: if (storedMap != null) {
281: values = (Set) storedMap.get(name);
282: }
283: if (values == null) {
284: values = new HashSet();
285: }
286:
287: if (isSingleMode) {
288:
289: if (name.equalsIgnoreCase("url")) {
290: values.add(s.getURL());
291: } else {
292: for (int i = 0;; i++) {
293: String v = s.getValue(name, i);
294: if (v == null) {
295: break;
296: }
297: values.add(v);
298: }
299: }
300: } else {
301: values.add(batchFillin);
302: }
303:
304: //Depending on the type and syntax, get value
305: if (attrType == DynamicGUI.TYPE_SINGLE) {
306: if (attrSyntax == DynamicGUI.SYNTAX_BOOLEAN) {
307: String trueValue = "true";
308: String falseValue = "false";
309: String value = "";
310: if (values != null) {
311: value = (String) values.iterator().next();
312: }
313: dg = new DynamicGUI(name, label, required,
314: attrType, attrSyntax, trueValue,
315: falseValue, value);
316: } else {
317: dg = new DynamicGUI(name, label, required,
318: attrType, attrSyntax, values);
319: }
320:
321: if (attrSyntax == DynamicGUI.SYNTAX_PASSWORD) {
322: dg.setConfirmPwdLabel("Confirm");
323: dg.setPasswordMessage(label + ": " + "Mismatch");
324: }
325: } else if (attrType == DynamicGUI.TYPE_SINGLE_CHOICE
326: || attrType == DynamicGUI.TYPE_MULTIPLE_CHOICE) {
327: //nothing
328: } else if (attrType == DynamicGUI.TYPE_LIST) {
329: dg = new DynamicGUI(name, label, required, attrType,
330: attrSyntax, values);
331: dg.setAddButtonStr(pvb.getLocalizedString("add.text"));
332: dg.setRemoveButtonStr(pvb
333: .getLocalizedString("remove.text"));
334: }
335: if (atClassificationField) {
336: String[] insTax = (String[]) pvb
337: .getRequestContext()
338: .getRequest()
339: .getSession()
340: .getAttribute(
341: TaxonomyBrowserView.SESION_ATTR_SELECTED_TAX
342: + editTimeStamp);
343: if (insTax != null) {
344: getRequestContext()
345: .getRequest()
346: .getSession()
347: .removeAttribute(
348: TaxonomyBrowserView.SESION_ATTR_SELECTED_TAX
349: + editTimeStamp);
350: values = new HashSet(insTax.length);
351: for (int i = 0; i < insTax.length; i++) {
352: values.add(insTax[i]);
353: }
354: dg.setValues(values);
355: }
356: }
357: if (isSingleMode) {
358: String isEditable = schema.getValue(name,
359: RDM.A_RDM_EDIT_ATTR);
360: dg.setReadOnly(isEditable == null
361: || !isEditable.equalsIgnoreCase("1"));
362: }
363: dgc.setValue(dg);
364: }
365: return movedToRow;
366: }
367:
368: /**
369: * Gets dynamic gui components from the Http request object and returns
370: * a List.
371: *
372: * @return List of DynamicGUIComp
373: */
374: public List getDynamicCompList() {
375: // cannot tell the size so give a default size
376: List dynamicGUIs = new ArrayList(10);
377: HttpServletRequest req = getRequestContext().getRequest();
378:
379: int count = 0;
380: while (true) {
381: DynamicGUI dGUI = DynamicGUIComp.createDynamicGUI(req,
382: getQualifiedName(), RD_AV_SET, count++);
383:
384: if (dGUI != null) {
385: dynamicGUIs.add(dGUI);
386: } else {
387: break;
388: }
389: }
390: return dynamicGUIs;
391: }
392:
393: public void loadSchema() {
394: SearchConfig csidconf = SearchConfig.getSearchConfig();
395: String schfn;
396: if ((schfn = SearchConfig.getValue(SearchConfig.SCHEMA)) == null) {
397: debugLogger.finer("PSSH_CSPSA0072");
398: }
399:
400: // Load the schema
401: debugLogger.log(Level.FINER, "PSSH_CSPSA0073", schfn);
402: SOIFInputStream ss = null;
403: try {
404: ss = new SOIFInputStream(schfn);
405: } catch (Exception e) {
406: debugLogger.log(Level.FINER, "PSSH_CSPSA0074", schfn);
407: }
408:
409: try {
410: schema = new RDMSchema(ss.readSOIF());
411: } catch (Exception e) {
412: debugLogger.log(Level.FINER, "PSSH_CSPSA0075", schfn);
413: }
414:
415: //printSchema();
416: }
417:
418: private SToken getSToken() {
419: if (st == null) {
420: HttpServletRequest req = getRequestContext().getRequest();
421: try {
422: SSOTokenManager manager = SSOTokenManager.getInstance();
423: SSOToken token = null;
424: token = manager.createSSOToken(req);
425: st = new SToken((Object) token, true, true);
426: } catch (SSOException e) {
427: debugLogger.log(Level.INFO, "PSSH_CSPSA0010", e
428: .getMessage());
429: // nothing, might be sso cookie is not there
430: }
431: }
432: return st;
433: }
434:
435: public void update() throws Exception {
436: ViewBean pvb = getParentViewBean();
437: editTimeStamp = (String) pvb
438: .getPageSessionAttribute("editTimeStamp");
439: urlList = (ArrayList) pvb.getRequestContext().getRequest()
440: .getSession().getAttribute("urls" + editTimeStamp);
441: queryString = (String) pvb.getPageSessionAttribute("query");
442: database = (String) getRequestContext().getRequest()
443: .getSession().getAttribute("database" + editTimeStamp);
444: List dynList = getDynamicCompList();
445: String tmpFile = CSConfig.getServerRoot() + File.separator
446: + "tmp" + File.separator + "tmpRDEditor."
447: + Long.toString(System.currentTimeMillis());
448: SOIFOutputStream so = new SOIFOutputStream(tmpFile);
449: String rdMgrCmd;
450: if (System.getProperty("os.name").startsWith("win")
451: || System.getProperty("os.name").startsWith("Win")
452: || System.getProperty("os.name").startsWith("WIN")) {
453: rdMgrCmd = "run-cs-cli.bat rdmgr ";
454: } else {
455: rdMgrCmd = "run-cs-cli rdmgr ";
456: }
457:
458: if (database != null) {
459: rdMgrCmd = rdMgrCmd + "-y " + database + " ";
460: }
461: if (queryString != null) {
462: String cmd = CSConfig.getServerRoot() + File.separator
463: + rdMgrCmd + "-Q '" + queryString + "' -a url";
464: int searchOption = Integer.parseInt(queryString.substring(
465: 0, 1));
466: String query = queryString.substring(2);
467: RDSearch rdSearch = new RDSearch();
468: int currPage = 1;
469: int numPerPage = 3000;
470: while (true) {
471: ArrayList resultList = rdSearch.search(database, query,
472: searchOption, (currPage - 1) * numPerPage + 1,
473: numPerPage, this .getSToken(), "url");
474: for (int i = 0; i < resultList.size(); i++) {
475: SOIF s = (SOIF) resultList.get(i);
476: s.remove("score");
477: for (int j = 0; j < dynList.size(); j++) {
478: DynamicGUI dynGUI = (DynamicGUI) dynList.get(j);
479: String name = dynGUI.getName();
480: Set vSet = dynGUI.getValues();
481: if (vSet.size() == 0) {
482: debugLogger.log(Level.FINER,
483: "PSSH_CSPSA0077", name);
484: s.insert(name, "", 0);
485: continue;
486: }
487: Iterator it = vSet.iterator();
488: int ndx = 0;
489: while (it.hasNext()) {
490: String value = (String) it.next();
491: if (!value.equals(batchFillin)) {
492: s.insert(name, value, ndx++);
493: }
494: }
495: }
496: so.write(s);
497: }
498: if (rdSearch.RDM_Hits > currPage * numPerPage) {
499: currPage++;
500: } else {
501: break;
502: }
503: }
504: } else if (urlList != null) {
505: if (urlList.size() == 1) {
506: updateOneRD(so, database, (String) urlList.get(0),
507: dynList);
508: } else {
509: for (int j = 0; j < urlList.size(); j++) {
510: SOIF newRD = new SOIF("DOCUMENT", (String) urlList
511: .get(j));
512: for (int i = 0; i < dynList.size(); i++) {
513: DynamicGUI dynGUI = (DynamicGUI) dynList.get(i);
514: String name = dynGUI.getName();
515: Set vSet = dynGUI.getValues();
516: if (vSet.size() == 0) {
517: newRD.insert(name, "", 0);
518: debugLogger.log(Level.FINER,
519: "PSSH_CSPSA0077", name);
520: continue;
521: }
522: debugLogger.log(Level.FINER, "PSSH_CSPSA0097",
523: name);
524: Iterator it = vSet.iterator();
525: int ndx = 0;
526: while (it.hasNext()) {
527: String value = (String) it.next();
528: debugLogger.log(Level.FINER,
529: "PSSH_CSPSA0078", value);
530: if (!value.equals(batchFillin)) {
531: newRD.insert(name, value, ndx++);
532: }
533: }
534: }
535: so.write(newRD);
536: }
537: }
538: }
539: so.close();
540: Runtime rt = Runtime.getRuntime();
541: String rdmgr = CSConfig.getServerRoot() + File.separator
542: + rdMgrCmd + "-m -P -q " + tmpFile;
543: debugLogger.log(Level.FINER, "PSSH_CSPSA0079", rdmgr);
544: Process p = rt.exec(rdmgr);
545: p.waitFor();
546: int exitValue = p.exitValue();
547: if (exitValue == 1) {
548: debugLogger.log(Level.FINER, "PSSH_CSPSA0080", Integer
549: .toString(exitValue));
550: }
551: }
552:
553: void updateOneRD(SOIFOutputStream so, String database,
554: String urlStr, List dynList) throws Exception {
555: SOIF rd = null;
556: RDSearch rdSearch = new RDSearch();
557: ArrayList rds = rdSearch.search(database, urlStr, 5, 1, 1, this
558: .getSToken());
559: rd = (SOIF) rds.get(0);
560: SOIF newRD = new SOIF("DOCUMENT", urlStr);
561: for (int i = 0; i < dynList.size(); i++) {
562: DynamicGUI dynGUI = (DynamicGUI) dynList.get(i);
563: String name = dynGUI.getName();
564: debugLogger.log(Level.FINER, "PSSH_CSPSA0076", name);
565: String isEditable = schema.getValue(name,
566: RDM.A_RDM_EDIT_ATTR);
567: if (isEditable == null || !isEditable.equalsIgnoreCase("1")) {
568: debugLogger.finer("PSSH_CSPSA0098");
569: continue;
570: }
571: int valueIndex = 0;
572: for (;; valueIndex++) {
573: String v = rd.getValue(name, valueIndex);
574: if (v == null) {
575: break;
576: }
577: debugLogger.log(Level.FINER, "PSSH_CSPSA0099", v);
578: }
579: Set vSet = dynGUI.getValues();
580: if (valueIndex == 0 && vSet.size() == 0) {
581: debugLogger.finer("PSSH_CSPSA0100");
582: continue;
583: }
584: if (vSet.size() == 0) {
585: debugLogger.log(Level.FINER, "PSSH_CSPSA0077", name);
586: newRD.insert(name, "", 0);
587: } else {
588: Iterator it = vSet.iterator();
589: int ndx = 0;
590: while (it.hasNext()) {
591: String value = (String) it.next();
592: debugLogger.log(Level.FINER, "PSSH_CSPSA0078",
593: value);
594: newRD.insert(name, value, ndx++);
595: }
596: }
597: }
598: so.write(newRD);
599: }
600:
601: public void handleTaxBrowserRequest(RequestInvocationEvent event) {
602: HashMap map = new HashMap();
603: String[] currTax = null;
604: List dynList = getDynamicCompList();
605: for (int i = 0; i < dynList.size(); i++) {
606: DynamicGUI dynGUI = (DynamicGUI) dynList.get(i);
607: String name = dynGUI.getName();
608: debugLogger.log(Level.FINER, "PSSH_CSPSA0081", dynGUI
609: .toString());
610: Set vSet = dynGUI.getValues();
611: if (name.equalsIgnoreCase("classification")) {
612: if (!vSet.isEmpty()) {
613: vSet.remove(batchFillin);
614: currTax = (String[]) vSet.toArray(new String[0]);
615: }
616: } else {
617: if (!vSet.isEmpty()) {
618: map.put(name, vSet);
619: }
620: }
621: }
622: ViewBean pvb = getParentViewBean();
623: editTimeStamp = (String) pvb
624: .getPageSessionAttribute("editTimeStamp");
625: debugLogger.log(Level.FINER, "PSSH_CSPSA0082", editTimeStamp);
626: pvb.getRequestContext().getRequest().getSession().setAttribute(
627: "DynamicGUI" + editTimeStamp, map);
628: pvb.setPageSessionAttribute(
629: TaxonomyBrowserView.SESION_ATTR_BROWSING_ON, "true");
630: pvb.getRequestContext().getRequest().getSession().setAttribute(
631: TaxonomyBrowserView.SESION_ATTR_SELECTED_TAX
632: + editTimeStamp,
633: (currTax == null ? new String[0] : currTax));
634: debugLogger.finer("PSSH_CSPSA0083");
635: pvb.forwardTo(getRequestContext());
636: }
637:
638: }
|