0001: /**********************************************************************************
0002: * $URL: https://source.sakaiproject.org/svn/citations/tags/sakai_2-4-1/citations-tool/tool/src/java/org/sakaiproject/citation/tool/CitationHelperAction.java $
0003: * $Id: CitationHelperAction.java 29917 2007-05-03 13:48:42Z ajpoland@iupui.edu $
0004: ***********************************************************************************
0005: *
0006: * Copyright (c) 2006 The Sakai Foundation.
0007: *
0008: * Licensed under the Educational Community License, Version 1.0 (the "License");
0009: * you may not use this file except in compliance with the License.
0010: * You may obtain a copy of the License at
0011: *
0012: * http://www.opensource.org/licenses/ecl1.php
0013: *
0014: * Unless required by applicable law or agreed to in writing, software
0015: * distributed under the License is distributed on an "AS IS" BASIS,
0016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017: * See the License for the specific language governing permissions and
0018: * limitations under the License.
0019: *
0020: **********************************************************************************/package org.sakaiproject.citation.tool;
0021:
0022: import java.io.IOException;
0023: import java.net.MalformedURLException;
0024: import java.net.URL;
0025: import java.util.Arrays;
0026: import java.util.Enumeration;
0027: import java.util.Hashtable;
0028: import java.util.Iterator;
0029: import java.util.List;
0030: import java.util.Map;
0031: import java.util.Set;
0032: import java.util.Stack;
0033: import java.util.Vector;
0034: import java.util.regex.Matcher;
0035: import java.util.regex.Pattern;
0036:
0037: import javax.servlet.http.HttpServletRequest;
0038: import javax.servlet.http.HttpServletResponse;
0039:
0040: import org.apache.commons.logging.Log;
0041: import org.apache.commons.logging.LogFactory;
0042: import org.sakaiproject.authz.api.SecurityAdvisor;
0043: import org.sakaiproject.authz.cover.SecurityService;
0044: import org.sakaiproject.cheftool.Context;
0045: import org.sakaiproject.cheftool.JetspeedRunData;
0046: import org.sakaiproject.cheftool.RunData;
0047: import org.sakaiproject.cheftool.VelocityPortlet;
0048: import org.sakaiproject.cheftool.VelocityPortletPaneledAction;
0049: import org.sakaiproject.citation.api.ActiveSearch;
0050: import org.sakaiproject.citation.api.Citation;
0051: import org.sakaiproject.citation.api.CitationCollection;
0052: import org.sakaiproject.citation.api.CitationHelper;
0053: import org.sakaiproject.citation.api.CitationIterator;
0054: import org.sakaiproject.citation.api.Schema;
0055: import org.sakaiproject.citation.api.SearchCategory;
0056: import org.sakaiproject.citation.api.SearchDatabaseHierarchy;
0057: import org.sakaiproject.citation.api.Schema.Field;
0058: import org.sakaiproject.citation.cover.CitationService;
0059: import org.sakaiproject.citation.cover.ConfigurationService;
0060: import org.sakaiproject.citation.cover.SearchManager;
0061: import org.sakaiproject.citation.util.api.SearchException;
0062: import org.sakaiproject.citation.util.api.SearchQuery;
0063: import org.sakaiproject.component.cover.ComponentManager;
0064: import org.sakaiproject.content.api.ContentHostingService;
0065: import org.sakaiproject.content.api.ContentResource;
0066: import org.sakaiproject.content.api.ContentResourceEdit;
0067: import org.sakaiproject.content.api.ResourceToolAction;
0068: import org.sakaiproject.content.api.ResourceToolActionPipe;
0069: import org.sakaiproject.content.api.ResourceType;
0070: import org.sakaiproject.entity.api.Reference;
0071: import org.sakaiproject.entity.api.ResourceProperties;
0072: import org.sakaiproject.entity.api.ResourcePropertiesEdit;
0073: import org.sakaiproject.entity.cover.EntityManager;
0074: import org.sakaiproject.event.api.NotificationService;
0075: import org.sakaiproject.event.api.SessionState;
0076: import org.sakaiproject.exception.IdInvalidException;
0077: import org.sakaiproject.exception.IdLengthException;
0078: import org.sakaiproject.exception.IdUniquenessException;
0079: import org.sakaiproject.exception.IdUnusedException;
0080: import org.sakaiproject.exception.InUseException;
0081: import org.sakaiproject.exception.OverQuotaException;
0082: import org.sakaiproject.exception.PermissionException;
0083: import org.sakaiproject.exception.ServerOverloadException;
0084: import org.sakaiproject.exception.TypeException;
0085: import org.sakaiproject.tool.api.Tool;
0086: import org.sakaiproject.tool.api.ToolException;
0087: import org.sakaiproject.tool.api.ToolSession;
0088: import org.sakaiproject.tool.cover.SessionManager;
0089: import org.sakaiproject.tool.cover.ToolManager;
0090: import org.sakaiproject.util.ParameterParser;
0091: import org.sakaiproject.util.ResourceLoader;
0092: import org.sakaiproject.util.Validator;
0093:
0094: /**
0095: *
0096: */
0097: public class CitationHelperAction extends VelocityPortletPaneledAction {
0098:
0099: /**
0100: * This class contains constants and utility methods to maintain state of
0101: * the advanced search form UI and process submitted data
0102: *
0103: * @author gbhatnag
0104: */
0105: protected static class AdvancedSearchHelper {
0106: /* ids for fields */
0107: public static final String KEYWORD_ID = "keyword";
0108: public static final String AUTHOR_ID = "author";
0109: public static final String TITLE_ID = "title";
0110: public static final String SUBJECT_ID = "subject";
0111: public static final String YEAR_ID = "year";
0112:
0113: /* keys to hold state information */
0114: public static final String STATE_FIELD1 = CitationHelper.CITATION_PREFIX
0115: + "advField1";
0116: public static final String STATE_FIELD2 = CitationHelper.CITATION_PREFIX
0117: + "advField2";
0118: public static final String STATE_FIELD3 = CitationHelper.CITATION_PREFIX
0119: + "advField3";
0120: public static final String STATE_FIELD4 = CitationHelper.CITATION_PREFIX
0121: + "advField4";
0122: public static final String STATE_FIELD5 = CitationHelper.CITATION_PREFIX
0123: + "advField5";
0124: public static final String STATE_CRITERIA1 = CitationHelper.CITATION_PREFIX
0125: + "advCriteria1";
0126: public static final String STATE_CRITERIA2 = CitationHelper.CITATION_PREFIX
0127: + "advCriteria2";
0128: public static final String STATE_CRITERIA3 = CitationHelper.CITATION_PREFIX
0129: + "advCriteria3";
0130: public static final String STATE_CRITERIA4 = CitationHelper.CITATION_PREFIX
0131: + "advCriteria4";
0132: public static final String STATE_CRITERIA5 = CitationHelper.CITATION_PREFIX
0133: + "advCriteria5";
0134:
0135: /**
0136: * Puts field selections stored in session state (using setFieldSelections())
0137: * into the given context
0138: *
0139: * @param context context to put field selections into
0140: * @param state SessionState to pull field selections from
0141: */
0142: public static void putFieldSelections(Context context,
0143: SessionState state) {
0144: /*
0145: context.put( "advField1", ( String )state.getAttribute( AdvancedSearchHelper.STATE_FIELD1 ) );
0146: context.put( "advField2", ( String )state.getAttribute( AdvancedSearchHelper.STATE_FIELD2 ) );
0147: context.put( "advField3", ( String )state.getAttribute( AdvancedSearchHelper.STATE_FIELD3 ) );
0148: context.put( "advField4", ( String )state.getAttribute( AdvancedSearchHelper.STATE_FIELD4 ) );
0149: context.put( "advField5", ( String )state.getAttribute( AdvancedSearchHelper.STATE_FIELD5 ) );
0150: */
0151:
0152: String advField1 = (String) state
0153: .getAttribute(AdvancedSearchHelper.STATE_FIELD1);
0154: String advField2 = (String) state
0155: .getAttribute(AdvancedSearchHelper.STATE_FIELD2);
0156: String advField3 = (String) state
0157: .getAttribute(AdvancedSearchHelper.STATE_FIELD3);
0158: String advField4 = (String) state
0159: .getAttribute(AdvancedSearchHelper.STATE_FIELD4);
0160: String advField5 = (String) state
0161: .getAttribute(AdvancedSearchHelper.STATE_FIELD5);
0162:
0163: if (advField1 != null && !advField1.trim().equals("")) {
0164: context.put("advField1", advField1);
0165: } else {
0166: context.put("advField1", KEYWORD_ID);
0167: }
0168:
0169: if (advField2 != null && !advField2.trim().equals("")) {
0170: context.put("advField2", advField2);
0171: } else {
0172: context.put("advField2", AUTHOR_ID);
0173: }
0174:
0175: if (advField3 != null && !advField3.trim().equals("")) {
0176: context.put("advField3", advField3);
0177: } else {
0178: context.put("advField3", TITLE_ID);
0179: }
0180:
0181: if (advField4 != null && !advField4.trim().equals("")) {
0182: context.put("advField4", advField4);
0183: } else {
0184: context.put("advField4", SUBJECT_ID);
0185: }
0186:
0187: if (advField5 != null && !advField5.trim().equals("")) {
0188: context.put("advField5", advField5);
0189: } else {
0190: context.put("advField5", YEAR_ID);
0191: }
0192: }
0193:
0194: /**
0195: * Puts field criteria stored in session state (using setFieldCriteria())
0196: * into the given context
0197: *
0198: * @param context context to put field criteria into
0199: * @param state SessionState to pull field criteria from
0200: */
0201: public static void putFieldCriteria(Context context,
0202: SessionState state) {
0203: context
0204: .put(
0205: "advCriteria1",
0206: (String) state
0207: .getAttribute(AdvancedSearchHelper.STATE_CRITERIA1));
0208: context
0209: .put(
0210: "advCriteria2",
0211: (String) state
0212: .getAttribute(AdvancedSearchHelper.STATE_CRITERIA2));
0213: context
0214: .put(
0215: "advCriteria3",
0216: (String) state
0217: .getAttribute(AdvancedSearchHelper.STATE_CRITERIA3));
0218: context
0219: .put(
0220: "advCriteria4",
0221: (String) state
0222: .getAttribute(AdvancedSearchHelper.STATE_CRITERIA4));
0223: context
0224: .put(
0225: "advCriteria5",
0226: (String) state
0227: .getAttribute(AdvancedSearchHelper.STATE_CRITERIA5));
0228: }
0229:
0230: /**
0231: * Sets user-selected fields in session state from request parameters
0232: *
0233: * @param params request parameters from doBeginSearch
0234: * @param state SessionState to store field selections
0235: */
0236: public static void setFieldSelections(ParameterParser params,
0237: SessionState state) {
0238: String advField1 = params.getString("advField1");
0239: if (advField1 != null && !advField1.trim().equals("")) {
0240: state.setAttribute(AdvancedSearchHelper.STATE_FIELD1,
0241: advField1);
0242: }
0243:
0244: String advField2 = params.getString("advField2");
0245: if (advField2 != null && !advField2.trim().equals("")) {
0246: state.setAttribute(AdvancedSearchHelper.STATE_FIELD2,
0247: advField2);
0248: }
0249:
0250: String advField3 = params.getString("advField3");
0251: if (advField3 != null && !advField3.trim().equals("")) {
0252: state.setAttribute(AdvancedSearchHelper.STATE_FIELD3,
0253: advField3);
0254: }
0255:
0256: String advField4 = params.getString("advField4");
0257: if (advField4 != null && !advField4.trim().equals("")) {
0258: state.setAttribute(AdvancedSearchHelper.STATE_FIELD4,
0259: advField4);
0260: }
0261:
0262: String advField5 = params.getString("advField5");
0263: if (advField5 != null && !advField5.trim().equals("")) {
0264: state.setAttribute(AdvancedSearchHelper.STATE_FIELD5,
0265: advField5);
0266: }
0267: }
0268:
0269: /**
0270: * Sets user-entered search field criteria in session state
0271: * from request parameters
0272: *
0273: * @param params request parameters from doBeginSearch
0274: * @param state SessionState to store field criteria
0275: */
0276: public static void setFieldCriteria(ParameterParser params,
0277: SessionState state) {
0278: String advCriteria1 = params.getString("advCriteria1");
0279: if (advCriteria1 != null && !advCriteria1.trim().equals("")) {
0280: state.setAttribute(
0281: AdvancedSearchHelper.STATE_CRITERIA1,
0282: advCriteria1);
0283: }
0284:
0285: String advCriteria2 = params.getString("advCriteria2");
0286: if (advCriteria2 != null && !advCriteria2.trim().equals("")) {
0287: state.setAttribute(
0288: AdvancedSearchHelper.STATE_CRITERIA2,
0289: advCriteria2);
0290: }
0291:
0292: String advCriteria3 = params.getString("advCriteria3");
0293: if (advCriteria3 != null && !advCriteria3.trim().equals("")) {
0294: state.setAttribute(
0295: AdvancedSearchHelper.STATE_CRITERIA3,
0296: advCriteria3);
0297: }
0298:
0299: String advCriteria4 = params.getString("advCriteria4");
0300: if (advCriteria4 != null && !advCriteria4.trim().equals("")) {
0301: state.setAttribute(
0302: AdvancedSearchHelper.STATE_CRITERIA4,
0303: advCriteria4);
0304: }
0305:
0306: String advCriteria5 = params.getString("advCriteria5");
0307: if (advCriteria5 != null && !advCriteria5.trim().equals("")) {
0308: state.setAttribute(
0309: AdvancedSearchHelper.STATE_CRITERIA5,
0310: advCriteria5);
0311: }
0312: }
0313:
0314: public static SearchQuery getAdvancedCriteria(SessionState state) {
0315: String advField1 = (String) state
0316: .getAttribute(AdvancedSearchHelper.STATE_FIELD1);
0317: String advField2 = (String) state
0318: .getAttribute(AdvancedSearchHelper.STATE_FIELD2);
0319: String advField3 = (String) state
0320: .getAttribute(AdvancedSearchHelper.STATE_FIELD3);
0321: String advField4 = (String) state
0322: .getAttribute(AdvancedSearchHelper.STATE_FIELD4);
0323: String advField5 = (String) state
0324: .getAttribute(AdvancedSearchHelper.STATE_FIELD5);
0325:
0326: String advCriteria1 = (String) state
0327: .getAttribute(AdvancedSearchHelper.STATE_CRITERIA1);
0328: String advCriteria2 = (String) state
0329: .getAttribute(AdvancedSearchHelper.STATE_CRITERIA2);
0330: String advCriteria3 = (String) state
0331: .getAttribute(AdvancedSearchHelper.STATE_CRITERIA3);
0332: String advCriteria4 = (String) state
0333: .getAttribute(AdvancedSearchHelper.STATE_CRITERIA4);
0334: String advCriteria5 = (String) state
0335: .getAttribute(AdvancedSearchHelper.STATE_CRITERIA5);
0336:
0337: SearchQuery searchQuery = new org.sakaiproject.citation.util.impl.SearchQuery();
0338:
0339: /*
0340: * put fielded, non-null criteria into the searchQuery
0341: */
0342: if (advField1 != null && advCriteria1 != null) {
0343: if (advField1.equalsIgnoreCase(KEYWORD_ID)) {
0344: searchQuery.addKeywords(advCriteria1);
0345: } else if (advField1.equalsIgnoreCase(AUTHOR_ID)) {
0346: searchQuery.addAuthor(advCriteria1);
0347: } else if (advField1.equalsIgnoreCase(TITLE_ID)) {
0348: searchQuery.addTitle(advCriteria1);
0349: } else if (advField1.equalsIgnoreCase(SUBJECT_ID)) {
0350: searchQuery.addSubject(advCriteria1);
0351: } else if (advField1.equalsIgnoreCase(YEAR_ID)) {
0352: searchQuery.addYear(advCriteria1);
0353: }
0354: }
0355:
0356: if (advField2 != null && advCriteria2 != null) {
0357: if (advField2.equalsIgnoreCase(KEYWORD_ID)) {
0358: searchQuery.addKeywords(advCriteria2);
0359: } else if (advField2.equalsIgnoreCase(AUTHOR_ID)) {
0360: searchQuery.addAuthor(advCriteria2);
0361: } else if (advField2.equalsIgnoreCase(TITLE_ID)) {
0362: searchQuery.addTitle(advCriteria2);
0363: } else if (advField2.equalsIgnoreCase(SUBJECT_ID)) {
0364: searchQuery.addSubject(advCriteria2);
0365: } else if (advField2.equalsIgnoreCase(YEAR_ID)) {
0366: searchQuery.addYear(advCriteria2);
0367: }
0368: }
0369:
0370: if (advField3 != null && advCriteria3 != null) {
0371: if (advField3.equalsIgnoreCase(KEYWORD_ID)) {
0372: searchQuery.addKeywords(advCriteria3);
0373: } else if (advField3.equalsIgnoreCase(AUTHOR_ID)) {
0374: searchQuery.addAuthor(advCriteria3);
0375: } else if (advField3.equalsIgnoreCase(TITLE_ID)) {
0376: searchQuery.addTitle(advCriteria3);
0377: } else if (advField3.equalsIgnoreCase(SUBJECT_ID)) {
0378: searchQuery.addSubject(advCriteria3);
0379: } else if (advField3.equalsIgnoreCase(YEAR_ID)) {
0380: searchQuery.addYear(advCriteria3);
0381: }
0382: }
0383:
0384: if (advField4 != null && advCriteria4 != null) {
0385: if (advField4.equalsIgnoreCase(KEYWORD_ID)) {
0386: searchQuery.addKeywords(advCriteria4);
0387: } else if (advField4.equalsIgnoreCase(AUTHOR_ID)) {
0388: searchQuery.addAuthor(advCriteria4);
0389: } else if (advField4.equalsIgnoreCase(TITLE_ID)) {
0390: searchQuery.addTitle(advCriteria4);
0391: } else if (advField4.equalsIgnoreCase(SUBJECT_ID)) {
0392: searchQuery.addSubject(advCriteria4);
0393: } else if (advField4.equalsIgnoreCase(YEAR_ID)) {
0394: searchQuery.addYear(advCriteria4);
0395: }
0396: }
0397:
0398: if (advField5 != null && advCriteria5 != null) {
0399: if (advField5.equalsIgnoreCase(KEYWORD_ID)) {
0400: searchQuery.addKeywords(advCriteria5);
0401: } else if (advField5.equalsIgnoreCase(AUTHOR_ID)) {
0402: searchQuery.addAuthor(advCriteria5);
0403: } else if (advField5.equalsIgnoreCase(TITLE_ID)) {
0404: searchQuery.addTitle(advCriteria5);
0405: } else if (advField5.equalsIgnoreCase(SUBJECT_ID)) {
0406: searchQuery.addSubject(advCriteria5);
0407: } else if (advField5.equalsIgnoreCase(YEAR_ID)) {
0408: searchQuery.addYear(advCriteria5);
0409: }
0410: }
0411:
0412: return searchQuery;
0413: }
0414:
0415: public static void clearAdvancedFormState(SessionState state) {
0416: state.removeAttribute(AdvancedSearchHelper.STATE_FIELD1);
0417: state.removeAttribute(AdvancedSearchHelper.STATE_FIELD2);
0418: state.removeAttribute(AdvancedSearchHelper.STATE_FIELD3);
0419: state.removeAttribute(AdvancedSearchHelper.STATE_FIELD4);
0420: state.removeAttribute(AdvancedSearchHelper.STATE_FIELD5);
0421:
0422: state.removeAttribute(AdvancedSearchHelper.STATE_CRITERIA1);
0423: state.removeAttribute(AdvancedSearchHelper.STATE_CRITERIA2);
0424: state.removeAttribute(AdvancedSearchHelper.STATE_CRITERIA3);
0425: state.removeAttribute(AdvancedSearchHelper.STATE_CRITERIA4);
0426: state.removeAttribute(AdvancedSearchHelper.STATE_CRITERIA5);
0427: }
0428: }
0429:
0430: protected final static Log logger = LogFactory
0431: .getLog(CitationHelperAction.class);
0432:
0433: public static ResourceLoader rb = new ResourceLoader("citations");
0434:
0435: public static final Integer DEFAULT_RESULTS_PAGE_SIZE = new Integer(
0436: 10);
0437: public static final Integer DEFAULT_LIST_PAGE_SIZE = new Integer(10);
0438:
0439: protected static final String ELEMENT_ID_CREATE_FORM = "createForm";
0440: protected static final String ELEMENT_ID_EDIT_FORM = "editForm";
0441: protected static final String ELEMENT_ID_LIST_FORM = "listForm";
0442: protected static final String ELEMENT_ID_SEARCH_FORM = "searchForm";
0443: protected static final String ELEMENT_ID_RESULTS_FORM = "resultsForm";
0444: protected static final String ELEMENT_ID_VIEW_FORM = "viewForm";
0445:
0446: /**
0447: * Mode defines a complete set of values describing the user's navigation intentions
0448: */
0449: public enum Mode {
0450: DATABASE, CREATE, EDIT, ERROR, LIST, ADD_CITATIONS, MESSAGE, SEARCH, RESULTS, VIEW;
0451: }
0452:
0453: /*
0454: * define a set of "fake" Modes (asynchronous calls) to maintain proper
0455: * back-button stack state
0456: */
0457: protected static Set<Mode> ignoreModes = new java.util.HashSet<Mode>();
0458: static {
0459: ignoreModes.add(Mode.DATABASE);
0460: ignoreModes.add(Mode.MESSAGE);
0461: }
0462:
0463: protected static final String PARAM_FORM_NAME = "FORM_NAME";
0464:
0465: protected static final String STATE_RESOURCES_ADD = CitationHelper.CITATION_PREFIX
0466: + "resources_add";
0467: protected static final String STATE_CURRENT_DATABASES = CitationHelper.CITATION_PREFIX
0468: + "current_databases";
0469: protected static final String STATE_BACK_BUTTON_STACK = CitationHelper.CITATION_PREFIX
0470: + "back-button_stack";
0471: protected static final String STATE_COLLECTION_ID = CitationHelper.CITATION_PREFIX
0472: + "collection_id";
0473: protected static final String STATE_CITATION_ID = CitationHelper.CITATION_PREFIX
0474: + "citation_id";
0475: protected static final String STATE_COLLECTION_TITLE = CitationHelper.CITATION_PREFIX
0476: + "collection_name";
0477: protected static final String STATE_CURRENT_REPOSITORY = CitationHelper.CITATION_PREFIX
0478: + "current_repository";
0479: protected static final String STATE_CURRENT_RESULTS = CitationHelper.CITATION_PREFIX
0480: + "current_results";
0481: protected static final String STATE_LIST_ITERATOR = CitationHelper.CITATION_PREFIX
0482: + "list_iterator";
0483: protected static final String STATE_LIST_PAGE = CitationHelper.CITATION_PREFIX
0484: + "list_page";
0485: protected static final String STATE_LIST_PAGE_SIZE = CitationHelper.CITATION_PREFIX
0486: + "list_page_size";
0487: protected static final String STATE_LIST_NO_SCROLL = CitationHelper.CITATION_PREFIX
0488: + "list_no_scroll";
0489: protected static final String STATE_NO_KEYWORDS = CitationHelper.CITATION_PREFIX
0490: + "no_search_criteria";
0491: protected static final String STATE_NO_DATABASES = CitationHelper.CITATION_PREFIX
0492: + "no_databases";
0493: protected static final String STATE_NO_RESULTS = CitationHelper.CITATION_PREFIX
0494: + "no_results";
0495: protected static final String STATE_SEARCH_HIERARCHY = CitationHelper.CITATION_PREFIX
0496: + "search_hierarchy";
0497: protected static final String STATE_SELECTED_CATEGORY = CitationHelper.CITATION_PREFIX
0498: + "selected_category";
0499: protected static final String STATE_DEFAULT_CATEGORY = CitationHelper.CITATION_PREFIX
0500: + "default_category";
0501: protected static final String STATE_UNAUTHORIZED_DB = CitationHelper.CITATION_PREFIX
0502: + "unauthorized_database";
0503: protected static final String STATE_REPOSITORY_MAP = CitationHelper.CITATION_PREFIX
0504: + "repository_map";
0505: protected static final String STATE_RESULTS_PAGE_SIZE = CitationHelper.CITATION_PREFIX
0506: + "results_page_size";
0507: protected static final String STATE_KEYWORDS = CitationHelper.CITATION_PREFIX
0508: + "search_criteria";
0509: protected static final String STATE_SEARCH_INFO = CitationHelper.CITATION_PREFIX
0510: + "search_info";
0511: protected static final String STATE_BASIC_SEARCH = CitationHelper.CITATION_PREFIX
0512: + "basic_search";
0513: protected static final String STATE_SEARCH_RESULTS = CitationHelper.CITATION_PREFIX
0514: + "search_results";
0515:
0516: protected static final String TEMPLATE_CREATE = "citation/create";
0517: protected static final String TEMPLATE_EDIT = "citation/edit";
0518: protected static final String TEMPLATE_ERROR = "citation/error";
0519: protected static final String TEMPLATE_LIST = "citation/list";
0520: protected static final String TEMPLATE_ADD_CITATIONS = "citation/add_citations";
0521: protected static final String TEMPLATE_MESSAGE = "citation/_message";
0522: protected static final String TEMPLATE_SEARCH = "citation/search";
0523: protected static final String TEMPLATE_RESULTS = "citation/results";
0524: protected static final String TEMPLATE_VIEW = "citation/view";
0525: protected static final String TEMPLATE_DATABASE = "citation/_databases";
0526:
0527: /**
0528: * Check for the helper-done case locally and handle it before letting the VPPA.toolModeDispatch() handle the actual dispatch.
0529: * @see org.sakaiproject.cheftool.VelocityPortletPaneledAction#toolModeDispatch(java.lang.String, java.lang.String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
0530: */
0531: protected void toolModeDispatch(String methodBase,
0532: String methodExt, HttpServletRequest req,
0533: HttpServletResponse res) throws ToolException {
0534: //SessionState sstate = getState(req);
0535: ToolSession toolSession = SessionManager
0536: .getCurrentToolSession();
0537:
0538: //String mode = (String) sstate.getAttribute(ResourceToolAction.STATE_MODE);
0539: //Object started = toolSession.getAttribute(ResourceToolAction.STARTED);
0540: Object done = toolSession.getAttribute(ResourceToolAction.DONE);
0541:
0542: if (done != null) {
0543: toolSession.removeAttribute(ResourceToolAction.STARTED);
0544: Tool tool = ToolManager.getCurrentTool();
0545:
0546: String url = (String) toolSession.getAttribute(tool.getId()
0547: + Tool.HELPER_DONE_URL);
0548:
0549: toolSession.removeAttribute(tool.getId()
0550: + Tool.HELPER_DONE_URL);
0551:
0552: try {
0553: res.sendRedirect(url); // TODO
0554: } catch (IOException e) {
0555: // Log.warn("chef", this + " : ", e);
0556: }
0557: return;
0558: }
0559:
0560: super .toolModeDispatch(methodBase, methodExt, req, res);
0561: }
0562:
0563: /**
0564: * build the context in helper mode.
0565: *
0566: * @return The name of the template to use.
0567: */
0568: public String buildCitationsPanelContext(VelocityPortlet portlet,
0569: Context context, RunData rundata, SessionState state) {
0570: initHelper(portlet, context, rundata, state);
0571:
0572: // always put appropriate bundle in velocity context
0573: context.put("tlang", rb);
0574:
0575: //context.put("mainFrameId", CitationHelper.CITATION_FRAME_ID);
0576: //context.put("citationToolId", CitationHelper.CITATION_ID);
0577: //context.put("specialHelperFlag", CitationHelper.SPECIAL_HELPER_ID);
0578: context.put("xilator", new Validator());
0579:
0580: // set me as the helper class
0581: // state.setAttribute(VelocityPortletPaneledAction.STATE_HELPER, CitationHelperAction.class.getName());
0582:
0583: String alertMessages = (String) state
0584: .getAttribute(STATE_MESSAGE);
0585: if (alertMessages != null) {
0586: context.put("alertMessages", alertMessages);
0587: state.removeAttribute(STATE_MESSAGE);
0588: }
0589:
0590: if (showBackButton(state)) {
0591: context.put("showBackButton", Boolean.TRUE);
0592: }
0593:
0594: // make sure observers are disabled
0595: VelocityPortletPaneledAction.disableObservers(state);
0596:
0597: String template = "";
0598: Mode mode = (Mode) state
0599: .getAttribute(CitationHelper.STATE_HELPER_MODE);
0600: if (mode == null) {
0601: mode = Mode.ADD_CITATIONS;
0602: setMode(state, mode);
0603: }
0604:
0605: switch (mode) {
0606: case ADD_CITATIONS:
0607: template = buildAddCitationsPanelContext(portlet, context,
0608: rundata, state);
0609: break;
0610: case CREATE:
0611: template = buildCreatePanelContext(portlet, context,
0612: rundata, state);
0613: break;
0614: case EDIT:
0615: template = buildEditPanelContext(portlet, context, rundata,
0616: state);
0617: break;
0618: case ERROR:
0619: template = buildErrorPanelContext(portlet, context,
0620: rundata, state);
0621: break;
0622: case LIST:
0623: template = buildListPanelContext(portlet, context, rundata,
0624: state);
0625: break;
0626: case MESSAGE:
0627: template = buildMessagePanelContext(portlet, context,
0628: rundata, state);
0629: break;
0630: case SEARCH:
0631: template = buildSearchPanelContext(portlet, context,
0632: rundata, state);
0633: break;
0634: case VIEW:
0635: template = buildViewPanelContext(portlet, context, rundata,
0636: state);
0637: break;
0638: }
0639:
0640: return template;
0641:
0642: } // buildCitationsPanelContext
0643:
0644: /**
0645: * @param state
0646: * @return
0647: */
0648: private boolean showBackButton(SessionState state) {
0649: Stack<Mode> stack = (Stack<Mode>) state
0650: .getAttribute(STATE_BACK_BUTTON_STACK);
0651:
0652: if (stack == null) {
0653: logger
0654: .warn("showBackButton getting null back-button stack from state");
0655: return false;
0656: }
0657:
0658: // only show the button if you have somewhere to go back to
0659: return (stack.size() > 1);
0660: }
0661:
0662: protected void putCitationCollectionDetails(Context context,
0663: SessionState state) {
0664: // get the citation list title
0665: String resourceId = (String) state
0666: .getAttribute(CitationHelper.RESOURCE_ID);
0667: ContentHostingService contentService = (ContentHostingService) ComponentManager
0668: .get("org.sakaiproject.content.api.ContentHostingService");
0669: String refStr = contentService.getReference(resourceId);
0670: Reference ref = EntityManager.newReference(refStr);
0671: String collectionTitle = null;
0672: if (ref != null) {
0673: collectionTitle = ref.getProperties().getProperty(
0674: ResourceProperties.PROP_DISPLAY_NAME);
0675: }
0676: if (collectionTitle != null
0677: && !collectionTitle.trim().equals("")) {
0678: context.put("collectionTitle", collectionTitle);
0679: } else {
0680: context.put("collectionTitle", (String) state
0681: .getAttribute(STATE_COLLECTION_TITLE));
0682: }
0683:
0684: // get the collection we're now working on
0685: String collectionId = (String) state
0686: .getAttribute(STATE_COLLECTION_ID);
0687: context.put("collectionId", collectionId);
0688:
0689: CitationCollection collection = null;
0690: try {
0691: collection = CitationService.getCollection(collectionId);
0692: } catch (IdUnusedException e) {
0693: logger
0694: .warn("buildAddCitationsPanelContext unable to access citationCollection "
0695: + collectionId);
0696: }
0697: if (collection == null) {
0698: logger
0699: .warn("buildAddCitationsPanelContext unable to access citationCollection "
0700: + collectionId);
0701: }
0702:
0703: // get the size of the list
0704: context.put("collectionSize", new Integer(collection.size()));
0705: }
0706:
0707: /**
0708: *
0709: * @param portlet
0710: * @param context
0711: * @param rundata
0712: * @param state
0713: * @return
0714: */
0715: public String buildAddCitationsPanelContext(
0716: VelocityPortlet portlet, Context context, RunData rundata,
0717: SessionState state) {
0718: // always put appropriate bundle in velocity context
0719: context.put("tlang", rb);
0720:
0721: // body onload handler
0722: context
0723: .put("sakai_onload",
0724: "setMainFrameHeight( window.name )");
0725:
0726: // get the citation list title
0727: String resourceId = (String) state
0728: .getAttribute(CitationHelper.RESOURCE_ID);
0729: ContentHostingService contentService = (ContentHostingService) ComponentManager
0730: .get("org.sakaiproject.content.api.ContentHostingService");
0731: String refStr = contentService.getReference(resourceId);
0732: Reference ref = EntityManager.newReference(refStr);
0733: String collectionTitle = null;
0734: if (ref != null) {
0735: collectionTitle = ref.getProperties().getProperty(
0736: ResourceProperties.PROP_DISPLAY_NAME);
0737: }
0738:
0739: if (collectionTitle != null
0740: && !collectionTitle.trim().equals("")) {
0741: context.put("collectionTitle", collectionTitle);
0742: } else {
0743: context.put("collectionTitle", (String) state
0744: .getAttribute(STATE_COLLECTION_TITLE));
0745: }
0746:
0747: // get the collection we're now working on
0748: String collectionId = (String) state
0749: .getAttribute(STATE_COLLECTION_ID);
0750: context.put("collectionId", collectionId);
0751:
0752: CitationCollection collection = null;
0753: try {
0754: collection = CitationService.getCollection(collectionId);
0755: } catch (IdUnusedException e) {
0756: logger
0757: .warn("buildAddCitationsPanelContext unable to access citationCollection "
0758: + collectionId);
0759: }
0760: if (collection == null) {
0761: logger
0762: .warn("buildAddCitationsPanelContext unable to access citationCollection "
0763: + collectionId);
0764: }
0765:
0766: // get the size of the list
0767: context.put("collectionSize", new Integer(collection.size()));
0768:
0769: // determine which features to display
0770: if (ConfigurationService.isGoogleScholarEnabled()) {
0771: String googleUrl = SearchManager
0772: .getGoogleScholarUrl(contentService
0773: .getUuid(resourceId));
0774: context.put("googleUrl", googleUrl);
0775:
0776: // object array for formatted messages
0777: Object[] googleArgs = { rb.getString("linkLabel.google") };
0778: context.put("googleArgs", googleArgs);
0779: }
0780:
0781: if (ConfigurationService.isLibrarySearchEnabled()
0782: && ConfigurationService
0783: .isDatabaseHierarchyXmlAvailable()) {
0784: context.put("searchLibrary", Boolean.TRUE);
0785: }
0786:
0787: // form name
0788: context.put(PARAM_FORM_NAME, ELEMENT_ID_CREATE_FORM);
0789:
0790: return TEMPLATE_ADD_CITATIONS;
0791:
0792: } // buildAddCitationsPanelContext
0793:
0794: /**
0795: * build the context.
0796: *
0797: * @return The name of the template to use.
0798: */
0799: public String buildCreatePanelContext(VelocityPortlet portlet,
0800: Context context, RunData rundata, SessionState state) {
0801: // always put appropriate bundle in velocity context
0802: context.put("tlang", rb);
0803:
0804: // validator
0805: context.put("xilator", new Validator());
0806:
0807: //context.put("sakai_onload", "setPopupHeight('create');checkinWithOpener('create');");
0808: //context.put("sakai_onunload", "window.opener.parent.popups['create']=null;");
0809:
0810: //context.put("mainFrameId", CitationHelper.CITATION_FRAME_ID);
0811: //context.put("citationToolId", CitationHelper.CITATION_ID);
0812: //context.put("specialHelperFlag", CitationHelper.SPECIAL_HELPER_ID);
0813:
0814: context.put(PARAM_FORM_NAME, ELEMENT_ID_CREATE_FORM);
0815:
0816: List schemas = CitationService.getSchemas();
0817: context.put("TEMPLATES", schemas);
0818:
0819: Schema defaultSchema = CitationService.getDefaultSchema();
0820: context.put("DEFAULT_TEMPLATE", defaultSchema);
0821:
0822: // Object array for instruction message
0823: Object[] instrArgs = { rb.getString("submit.create") };
0824: context.put("instrArgs", instrArgs);
0825:
0826: return TEMPLATE_CREATE;
0827:
0828: } // buildCreatePanelContext
0829:
0830: /**
0831: * @param portlet
0832: * @param context
0833: * @param rundata
0834: * @param state
0835: * @return
0836: */
0837: public String buildDatabasePanelContext(VelocityPortlet portlet,
0838: Context context, RunData rundata, SessionState state) {
0839: // always put appropriate bundle in velocity context
0840: context.put("tlang", rb);
0841:
0842: // get hierarchy
0843: SearchDatabaseHierarchy hierarchy = (SearchDatabaseHierarchy) state
0844: .getAttribute(STATE_SEARCH_HIERARCHY);
0845:
0846: // get selected category
0847: SearchCategory category = (SearchCategory) state
0848: .getAttribute(STATE_SELECTED_CATEGORY);
0849:
0850: if (category == null) {
0851: // bad...
0852: logger
0853: .warn("buildDatabasePanelContext getting null selected "
0854: + "category from state.");
0855: }
0856:
0857: // put selected category into context
0858: context.put("category", category);
0859:
0860: // maxDbNum
0861: Integer maxDbNum = new Integer(hierarchy
0862: .getNumMaxSearchableDb());
0863: context.put("maxDbNum", maxDbNum);
0864:
0865: // object array for formatted messages
0866: Object[] maxDbArgs = { maxDbNum };
0867: context.put("maxDbArgs", maxDbArgs);
0868:
0869: // validator
0870: context.put("xilator", new Validator());
0871:
0872: return TEMPLATE_DATABASE;
0873: } // buildDatabasePanelContext
0874:
0875: /**
0876: * @param portlet
0877: * @param context
0878: * @param rundata
0879: * @param state
0880: * @return
0881: */
0882: public String buildEditPanelContext(VelocityPortlet portlet,
0883: Context context, RunData rundata, SessionState state) {
0884: // always put appropriate bundle in velocity context
0885: context.put("tlang", rb);
0886:
0887: // validator
0888: context.put("xilator", new Validator());
0889:
0890: context.put("sakai_onload",
0891: "setMainFrameHeight( window.name ); heavyResize();");
0892: //context.put("sakai_onunload", "window.opener.parent.popups['edit']=null;");
0893:
0894: //context.put("mainFrameId", CitationHelper.CITATION_FRAME_ID);
0895: //context.put("citationToolId", CitationHelper.CITATION_ID);
0896: //context.put("specialHelperFlag", CitationHelper.SPECIAL_HELPER_ID);
0897:
0898: context.put(PARAM_FORM_NAME, ELEMENT_ID_CREATE_FORM);
0899:
0900: Citation citation = (Citation) state
0901: .getAttribute(CitationHelper.CITATION_EDIT_ITEM);
0902: if (citation == null) {
0903: doEdit(rundata);
0904: citation = (Citation) state
0905: .getAttribute(CitationHelper.CITATION_EDIT_ITEM);
0906: }
0907: context.put("citation", citation);
0908:
0909: String citationId = (String) state
0910: .getAttribute(CitationHelper.CITATION_EDIT_ID);
0911: String collectionId = (String) state
0912: .getAttribute(STATE_COLLECTION_ID);
0913: context.put("citationId", citationId);
0914: context.put("collectionId", collectionId);
0915:
0916: List schemas = CitationService.getSchemas();
0917: context.put("TEMPLATES", schemas);
0918:
0919: context.put("DEFAULT_TEMPLATE", citation.getSchema());
0920:
0921: // Object array for formatted instruction
0922: Object[] instrArgs = { rb.getString("submit.edit") };
0923: context.put("instrArgs", instrArgs);
0924:
0925: return TEMPLATE_EDIT;
0926: }
0927:
0928: /**
0929: * @param portlet
0930: * @param context
0931: * @param rundata
0932: * @param state
0933: * @return
0934: */
0935: private String buildErrorPanelContext(VelocityPortlet portlet,
0936: Context context, RunData rundata, SessionState state) {
0937: //context.put("sakai_onload", "setPopupHeight('error');");
0938: //context.put("sakai_onunload", "window.opener.parent.popups['error']=null;");
0939:
0940: return TEMPLATE_ERROR;
0941: }
0942:
0943: /**
0944: * build the context.
0945: *
0946: * @return The name of the template to use.
0947: */
0948: public String buildListPanelContext(VelocityPortlet portlet,
0949: Context context, RunData rundata, SessionState state) {
0950: // always put appropriate bundle in velocity context
0951: context.put("tlang", rb);
0952:
0953: // validator
0954: context.put("xilator", new Validator());
0955:
0956: if (state.removeAttribute(STATE_LIST_NO_SCROLL) == null) {
0957: context.put("sakai_onload",
0958: "setMainFrameHeight( window.name )");
0959: } else {
0960: context.put("sakai_onload", "resizeFrame()");
0961: }
0962:
0963: //context.put("mainFrameId", CitationHelper.CITATION_FRAME_ID);
0964: //context.put("citationToolId", CitationHelper.CITATION_ID);
0965: //context.put("specialHelperFlag", CitationHelper.SPECIAL_HELPER_ID);
0966:
0967: // get the citation list title
0968: String resourceId = (String) state
0969: .getAttribute(CitationHelper.RESOURCE_ID);
0970: ContentHostingService contentService = (ContentHostingService) ComponentManager
0971: .get("org.sakaiproject.content.api.ContentHostingService");
0972: String refStr = contentService.getReference(resourceId);
0973: Reference ref = EntityManager.newReference(refStr);
0974: String collectionTitle = null;
0975: if (ref != null) {
0976: collectionTitle = ref.getProperties().getProperty(
0977: ResourceProperties.PROP_DISPLAY_NAME);
0978: }
0979: if (collectionTitle != null
0980: && !collectionTitle.trim().equals("")) {
0981: context.put("collectionTitle", collectionTitle);
0982: } else {
0983: context.put("collectionTitle", (String) state
0984: .getAttribute(STATE_COLLECTION_TITLE));
0985: }
0986:
0987: context.put("openUrlLabel", ConfigurationService
0988: .getSiteConfigOpenUrlLabel());
0989:
0990: context.put(PARAM_FORM_NAME, ELEMENT_ID_LIST_FORM);
0991:
0992: CitationCollection collection = null;
0993: String collectionId = (String) state
0994: .getAttribute(STATE_COLLECTION_ID);
0995: if (collectionId == null) {
0996: collection = CitationService.addCollection();
0997: state.setAttribute(STATE_COLLECTION_ID, collection.getId());
0998: } else {
0999: try {
1000: collection = CitationService
1001: .getCollection(collectionId);
1002: } catch (IdUnusedException e) {
1003: logger
1004: .warn("CitationHelperAction.buildListPanelContext unable to access citationCollection "
1005: + collectionId);
1006: }
1007: if (collection == null) {
1008: collection = CitationService.addCollection();
1009: state.setAttribute(STATE_COLLECTION_ID, collection
1010: .getId());
1011: }
1012: }
1013:
1014: // collection size
1015: context.put("collectionSize", new Integer(collection.size()));
1016:
1017: // export URLs
1018: String exportUrlSel = collection
1019: .getUrl(CitationService.REF_TYPE_EXPORT_RIS_SEL);
1020: String exportUrlAll = collection
1021: .getUrl(CitationService.REF_TYPE_EXPORT_RIS_ALL);
1022: context.put("exportUrlSel", exportUrlSel);
1023: context.put("exportUrlAll", exportUrlAll);
1024:
1025: Integer listPageSize = (Integer) state
1026: .getAttribute(STATE_LIST_PAGE_SIZE);
1027: if (listPageSize == null) {
1028: listPageSize = DEFAULT_LIST_PAGE_SIZE;
1029: state.setAttribute(STATE_LIST_PAGE_SIZE, listPageSize);
1030: }
1031: context.put("listPageSize", listPageSize);
1032:
1033: CitationIterator newIterator = collection.iterator();
1034: CitationIterator oldIterator = (CitationIterator) state
1035: .getAttribute(STATE_LIST_ITERATOR);
1036: if (oldIterator != null) {
1037: newIterator.setPageSize(listPageSize.intValue());
1038: newIterator.setPage(oldIterator.getPage());
1039: }
1040: context.put("citations", newIterator);
1041: context.put("collectionId", collection.getId());
1042: if (!collection.isEmpty()) {
1043: context.put("show_citations", Boolean.TRUE);
1044:
1045: int page = newIterator.getPage();
1046: int pageSize = newIterator.getPageSize();
1047: int totalSize = collection.size();
1048:
1049: int start = page * pageSize + 1;
1050: int end = Math.min((page + 1) * pageSize, totalSize);
1051:
1052: Integer[] position = { new Integer(start),
1053: new Integer(end), new Integer(totalSize) };
1054: String showing = (String) rb.getFormattedMessage(
1055: "showing.results", position);
1056: context.put("showing", showing);
1057: }
1058: state.setAttribute(STATE_LIST_ITERATOR, newIterator);
1059:
1060: // back to search results button control
1061: context.put("searchResults", state
1062: .getAttribute(STATE_SEARCH_RESULTS));
1063:
1064: // constant schema identifier
1065: context.put("titleProperty", Schema.TITLE);
1066:
1067: /*
1068: * Object arrays for formatted messages
1069: */
1070: Object[] instrMainArgs = { ConfigurationService
1071: .getSiteConfigOpenUrlLabel() };
1072: context.put("instrMainArgs", instrMainArgs);
1073:
1074: Object[] instrSubArgs = { rb.getString("label.finish") };
1075: context.put("instrSubArgs", instrSubArgs);
1076:
1077: Object[] emptyListArgs = { rb.getString("label.menu") };
1078: context.put("emptyListArgs", emptyListArgs);
1079:
1080: return TEMPLATE_LIST;
1081:
1082: } // buildListPanelContext
1083:
1084: /**
1085: * build the context.
1086: *
1087: * @return The name of the template to use.
1088: */
1089: public String buildMainPanelContext(VelocityPortlet portlet,
1090: Context context, RunData rundata, SessionState state) {
1091: initHelper(portlet, context, rundata, state);
1092:
1093: // always put appropriate bundle in velocity context
1094: context.put("tlang", rb);
1095:
1096: //context.put("mainFrameId", CitationHelper.CITATION_FRAME_ID);
1097: //context.put("citationToolId", CitationHelper.CITATION_ID);
1098: //context.put("specialHelperFlag", CitationHelper.SPECIAL_HELPER_ID);
1099:
1100: // always put whether this is a Resources Add or Revise operation
1101: if (state.getAttribute(STATE_RESOURCES_ADD) != null) {
1102: context.put("resourcesAddAction", Boolean.TRUE);
1103: }
1104:
1105: if (showBackButton(state)) {
1106: context.put("showBackButton", Boolean.TRUE);
1107: }
1108:
1109: // make sure observers are disabled
1110: VelocityPortletPaneledAction.disableObservers(state);
1111:
1112: String template = "";
1113: Mode mode = (Mode) state
1114: .getAttribute(CitationHelper.STATE_HELPER_MODE);
1115: if (mode == null) {
1116: // mode really shouldn't be null here
1117: logger
1118: .warn("buildMainPanelContext() getting null Mode from state");
1119: mode = Mode.ADD_CITATIONS;
1120: setMode(state, mode);
1121: }
1122:
1123: // add mode to the template
1124: context.put("citationsHelperMode", mode);
1125:
1126: switch (mode) {
1127: case ADD_CITATIONS:
1128: template = buildAddCitationsPanelContext(portlet, context,
1129: rundata, state);
1130: break;
1131: case CREATE:
1132: template = buildCreatePanelContext(portlet, context,
1133: rundata, state);
1134: break;
1135: case DATABASE:
1136: template = buildDatabasePanelContext(portlet, context,
1137: rundata, state);
1138: break;
1139: case EDIT:
1140: template = buildEditPanelContext(portlet, context, rundata,
1141: state);
1142: break;
1143: case ERROR:
1144: template = buildErrorPanelContext(portlet, context,
1145: rundata, state);
1146: break;
1147: case LIST:
1148: template = buildListPanelContext(portlet, context, rundata,
1149: state);
1150: break;
1151: case MESSAGE:
1152: template = buildMessagePanelContext(portlet, context,
1153: rundata, state);
1154: break;
1155: case SEARCH:
1156: template = buildSearchPanelContext(portlet, context,
1157: rundata, state);
1158: break;
1159: case RESULTS:
1160: template = buildResultsPanelContext(portlet, context,
1161: rundata, state);
1162: break;
1163: case VIEW:
1164: template = buildViewPanelContext(portlet, context, rundata,
1165: state);
1166: break;
1167: }
1168:
1169: return template;
1170:
1171: } // buildMainPanelContext
1172:
1173: /**
1174: * @param portlet
1175: * @param context
1176: * @param rundata
1177: * @param state
1178: * @return
1179: */
1180: public String buildMessagePanelContext(VelocityPortlet portlet,
1181: Context context, RunData rundata, SessionState state) {
1182: context.put("sakai_onload", "");
1183: //context.put("FORM_NAME", "messageForm");
1184:
1185: context
1186: .put("citationId", state
1187: .getAttribute(STATE_CITATION_ID));
1188:
1189: // get the collection we're now working on
1190: String collectionId = (String) state
1191: .getAttribute(STATE_COLLECTION_ID);
1192: context.put("collectionId", collectionId);
1193:
1194: CitationCollection collection = null;
1195: try {
1196: collection = CitationService.getCollection(collectionId);
1197: } catch (IdUnusedException e) {
1198: logger
1199: .warn("buildAddCitationsPanelContext unable to access citationCollection "
1200: + collectionId);
1201: }
1202: if (collection == null) {
1203: logger
1204: .warn("buildAddCitationsPanelContext unable to access citationCollection "
1205: + collectionId);
1206: }
1207:
1208: // get the size of the list
1209: context.put("citationCount", new Integer(collection.size()));
1210:
1211: return TEMPLATE_MESSAGE;
1212: }
1213:
1214: /**
1215: *
1216: * @param portlet
1217: * @param context
1218: * @param rundata
1219: * @param state
1220: * @return
1221: */
1222: public String buildResultsPanelContext(VelocityPortlet portlet,
1223: Context context, RunData rundata, SessionState state) {
1224: // always put appropriate bundle in velocity context
1225: context.put("tlang", rb);
1226:
1227: // validators
1228: context.put("TextValidator", new QuotedTextValidator());
1229: context.put("xilator", new Validator());
1230:
1231: // javascript to run on page load
1232: context.put("sakai_onload",
1233: "setMainFrameHeight( window.name ); highlightButtonSelections( '"
1234: + rb.getString("remove.results") + "' )");
1235:
1236: // put the citation list title and size
1237: putCitationCollectionDetails(context, state);
1238:
1239: // signal basic/advanced search
1240: Object basicSearch = state.getAttribute(STATE_BASIC_SEARCH);
1241: context.put("basicSearch", basicSearch);
1242: if (basicSearch != null) {
1243: context.put("searchType", ActiveSearch.BASIC_SEARCH_TYPE);
1244: } else {
1245: context
1246: .put("searchType",
1247: ActiveSearch.ADVANCED_SEARCH_TYPE);
1248: }
1249:
1250: /*
1251: * SEARCH RESULTS
1252: */
1253: ActiveSearch searchResults = (ActiveSearch) state
1254: .getAttribute(STATE_SEARCH_RESULTS);
1255: if (searchResults != null) {
1256: context.put("searchResults", searchResults);
1257: List currentResults = (List) state
1258: .getAttribute(STATE_CURRENT_RESULTS);
1259: context.put("currentResults", currentResults);
1260:
1261: Integer[] position = {
1262: new Integer(searchResults.getFirstRecordIndex() + 1),
1263: new Integer(searchResults.getLastRecordIndex()),
1264: searchResults.getNumRecordsFound() };
1265: String showing = (String) rb.getFormattedMessage(
1266: "showing.results", position);
1267: context.put("showing", showing);
1268: }
1269:
1270: // selected databases
1271: String[] databaseIds = (String[]) state
1272: .getAttribute(STATE_CURRENT_DATABASES);
1273: context.put("selectedDatabases", databaseIds);
1274:
1275: // load basic/advanced search form state
1276: loadSearchFormState(context, state);
1277:
1278: /*
1279: * OTHER CONTEXT PARAMS
1280: */
1281: // searchInfo
1282: ActiveSearch searchInfo = (ActiveSearch) state
1283: .getAttribute(STATE_SEARCH_INFO);
1284: context.put("searchInfo", searchInfo);
1285:
1286: // form name
1287: context.put(PARAM_FORM_NAME, ELEMENT_ID_RESULTS_FORM);
1288:
1289: // OpenURL Label
1290: context.put("openUrlLabel", ConfigurationService
1291: .getSiteConfigOpenUrlLabel());
1292:
1293: // object arrays for formatted messages
1294: Object[] instrMainArgs = { rb.getString("add.results") };
1295: context.put("instrMainArgs", instrMainArgs);
1296:
1297: Object[] instrSubArgs = { rb.getString("label.new.search") };
1298: context.put("instrSubArgs", instrSubArgs);
1299:
1300: /*
1301: * ERROR CHECKING
1302: */
1303: String alertMessages = (String) state
1304: .removeAttribute(STATE_MESSAGE);
1305: if (alertMessages != null) {
1306: context.put("alertMessages", alertMessages);
1307: }
1308:
1309: Object noResults = state.removeAttribute(STATE_NO_RESULTS);
1310: if (noResults != null) {
1311: context.put("noResults", noResults);
1312: }
1313:
1314: Object noSearch = state.removeAttribute(STATE_NO_KEYWORDS);
1315: if (noSearch != null) {
1316: context.put("noSearch", noSearch);
1317: }
1318:
1319: Object noDatabases = state.removeAttribute(STATE_NO_DATABASES);
1320: if (noDatabases != null) {
1321: context.put("noDatabases", noDatabases);
1322: }
1323:
1324: return TEMPLATE_RESULTS;
1325:
1326: } // buildResultsPanelContext
1327:
1328: /**
1329: * @param portlet
1330: * @param context
1331: * @param rundata
1332: * @param state
1333: * @return
1334: */
1335: public String buildSearchPanelContext(VelocityPortlet portlet,
1336: Context context, RunData rundata, SessionState state) {
1337: // always put appropriate bundle in velocity context
1338: context.put("tlang", rb);
1339:
1340: // validators
1341: context.put("TextValidator", new QuotedTextValidator());
1342: context.put("xilator", new Validator());
1343:
1344: // javascript to run on page load
1345: context.put("sakai_onload",
1346: "setMainFrameHeight( window.name ); showTopCategory()");
1347:
1348: // put citation list title/size
1349: putCitationCollectionDetails(context, state);
1350:
1351: // resource-related
1352: String resourceId = (String) state
1353: .getAttribute(CitationHelper.RESOURCE_ID);
1354: ContentHostingService contentService = (ContentHostingService) ComponentManager
1355: .get("org.sakaiproject.content.api.ContentHostingService");
1356: String guid = contentService.getUuid(resourceId);
1357: context.put("RESOURCE_ID", guid);
1358:
1359: // category information from hierarchy
1360: SearchDatabaseHierarchy hierarchy = (SearchDatabaseHierarchy) state
1361: .getAttribute(STATE_SEARCH_HIERARCHY);
1362: context.put("defaultCategory", hierarchy.getDefaultCategory());
1363: context.put("categoryListing", hierarchy.getCategoryListing());
1364:
1365: // load basic/advanced search form state
1366: loadSearchFormState(context, state);
1367:
1368: /*
1369: * MISCELLANEOUS CONTEXT PARAMS
1370: */
1371: // default to basicSearch
1372: context.put("basicSearch", state
1373: .getAttribute(STATE_BASIC_SEARCH));
1374:
1375: // searchInfo
1376: ActiveSearch searchInfo = (ActiveSearch) state
1377: .getAttribute(STATE_SEARCH_INFO);
1378: context.put("searchInfo", searchInfo);
1379:
1380: // max number of searchable databases
1381: Integer maxDbNum = new Integer(hierarchy
1382: .getNumMaxSearchableDb());
1383: context.put("maxDbNum", maxDbNum);
1384:
1385: // form name
1386: context.put(PARAM_FORM_NAME, ELEMENT_ID_SEARCH_FORM);
1387:
1388: // OpenURL Label
1389: context.put("openUrlLabel", ConfigurationService
1390: .getSiteConfigOpenUrlLabel());
1391:
1392: // object arrays for formatted messages
1393: Object[] instrArgs = { rb.getString("submit.search") };
1394: context.put("instrArgs", instrArgs);
1395:
1396: return TEMPLATE_SEARCH;
1397:
1398: } // buildSearchPanelContext
1399:
1400: /**
1401: * @param portlet
1402: * @param context
1403: * @param rundata
1404: * @param state
1405: * @return
1406: */
1407: public String buildViewPanelContext(VelocityPortlet portlet,
1408: Context context, RunData rundata, SessionState state) {
1409: // always put appropriate bundle in velocity context
1410: context.put("tlang", rb);
1411:
1412: // validator
1413: context.put("xilator", new Validator());
1414:
1415: //context.put("sakai_onload", "setMainFrameHeight('" + CitationHelper.CITATION_FRAME_ID + "');");
1416:
1417: //context.put("mainFrameId", CitationHelper.CITATION_FRAME_ID);
1418: //context.put("citationToolId", CitationHelper.CITATION_ID);
1419: //context.put("specialHelperFlag", CitationHelper.SPECIAL_HELPER_ID);
1420:
1421: context.put(PARAM_FORM_NAME, ELEMENT_ID_VIEW_FORM);
1422:
1423: Citation citation = (Citation) state
1424: .getAttribute(CitationHelper.CITATION_VIEW_ITEM);
1425: if (citation == null) {
1426: doEdit(rundata);
1427: citation = (Citation) state
1428: .getAttribute(CitationHelper.CITATION_VIEW_ITEM);
1429: }
1430: context.put("citation", citation);
1431:
1432: String citationId = (String) state
1433: .getAttribute(CitationHelper.CITATION_VIEW_ID);
1434: String collectionId = (String) state
1435: .getAttribute(STATE_COLLECTION_ID);
1436: context.put("citationId", citationId);
1437: context.put("collectionId", collectionId);
1438:
1439: List schemas = CitationService.getSchemas();
1440: context.put("TEMPLATES", schemas);
1441:
1442: context.put("DEFAULT_TEMPLATE", citation.getSchema());
1443:
1444: return TEMPLATE_VIEW;
1445:
1446: } // buildViewPanelContext
1447:
1448: /**
1449: *
1450: * @param context
1451: * @param state
1452: */
1453: protected void loadSearchFormState(Context context,
1454: SessionState state) {
1455: // remember data previously entered
1456: if (state.getAttribute(STATE_BASIC_SEARCH) != null) {
1457: /* basic search */
1458: context.put("keywords", (String) state
1459: .getAttribute(STATE_KEYWORDS));
1460:
1461: // default advanced search selections
1462: context.put("advField1", AdvancedSearchHelper.KEYWORD_ID);
1463: context.put("advField2", AdvancedSearchHelper.AUTHOR_ID);
1464: context.put("advField3", AdvancedSearchHelper.TITLE_ID);
1465: context.put("advField4", AdvancedSearchHelper.SUBJECT_ID);
1466: context.put("advField5", AdvancedSearchHelper.YEAR_ID);
1467: } else {
1468: /* advanced search */
1469:
1470: // field selections
1471: AdvancedSearchHelper.putFieldSelections(context, state);
1472:
1473: // field criteria
1474: AdvancedSearchHelper.putFieldCriteria(context, state);
1475: }
1476:
1477: // basic/advanced search types
1478: context.put("basicSearchType", ActiveSearch.BASIC_SEARCH_TYPE);
1479: context.put("advancedSearchType",
1480: ActiveSearch.ADVANCED_SEARCH_TYPE);
1481: }
1482:
1483: /**
1484: *
1485: */
1486: public void doFinish(RunData data) {
1487: ToolSession toolSession = SessionManager
1488: .getCurrentToolSession();
1489: ResourceToolActionPipe pipe = (ResourceToolActionPipe) toolSession
1490: .getAttribute(ResourceToolAction.ACTION_PIPE);
1491:
1492: int citationCount = 0;
1493:
1494: if (pipe.getAction().getActionType() == ResourceToolAction.ActionType.CREATE) {
1495: SessionState state = ((JetspeedRunData) data)
1496: .getPortletSessionState(((JetspeedRunData) data)
1497: .getJs_peid());
1498:
1499: // delete the temporary resource
1500: String temporaryResourceId = (String) state
1501: .getAttribute(CitationHelper.RESOURCE_ID);
1502: ContentHostingService contentService = (ContentHostingService) ComponentManager
1503: .get("org.sakaiproject.content.api.ContentHostingService");
1504: ContentResource tempResource = null;
1505: try {
1506: // get the temp resource
1507: tempResource = contentService
1508: .getResource(temporaryResourceId);
1509:
1510: // use the temp resource to 'create' the real resource
1511: pipe.setRevisedContent(tempResource.getContent());
1512:
1513: // remove the temp resource
1514: if (CitationService
1515: .allowRemoveCitationList(temporaryResourceId)) {
1516: // setup a SecurityAdvisor
1517: SecurityService
1518: .pushAdvisor(new CitationListSecurityAdviser(
1519: SessionManager
1520: .getCurrentSessionUserId(),
1521: ContentHostingService.AUTH_RESOURCE_REMOVE_ANY,
1522: tempResource.getReference()));
1523:
1524: // remove temp resource
1525: contentService.removeResource(temporaryResourceId);
1526:
1527: // clear advisors
1528: SecurityService.clearAdvisors();
1529:
1530: tempResource = null;
1531: }
1532: } catch (PermissionException e) {
1533: // TODO Auto-generated catch block
1534: logger.warn("PermissionException ", e);
1535: } catch (IdUnusedException e) {
1536: // TODO Auto-generated catch block
1537: logger.warn("IdUnusedException ", e);
1538: } catch (TypeException e) {
1539: // TODO Auto-generated catch block
1540: logger.warn("TypeException ", e);
1541: } catch (InUseException e) {
1542: // TODO Auto-generated catch block
1543: logger.warn("InUseException ", e);
1544: } catch (ServerOverloadException e) {
1545: // TODO Auto-generated catch block
1546: logger.warn("ServerOverloadException ", e);
1547: }
1548: }
1549:
1550: // set content (mime) type
1551: pipe.setRevisedMimeType(ResourceType.MIME_TYPE_HTML);
1552: pipe.setRevisedResourceProperty(
1553: ResourceProperties.PROP_CONTENT_TYPE,
1554: ResourceType.MIME_TYPE_HTML);
1555:
1556: // set the alternative_reference to point to reference_root for CitationService
1557: pipe
1558: .setRevisedResourceProperty(
1559: ContentHostingService.PROP_ALTERNATE_REFERENCE,
1560: org.sakaiproject.citation.api.CitationService.REFERENCE_ROOT);
1561:
1562: SessionState state = ((JetspeedRunData) data)
1563: .getPortletSessionState(((JetspeedRunData) data)
1564: .getJs_peid());
1565: // get the collection we're now working on
1566: String collectionId = (String) state
1567: .getAttribute(STATE_COLLECTION_ID);
1568:
1569: CitationCollection collection = null;
1570: try {
1571: collection = CitationService.getCollection(collectionId);
1572: } catch (IdUnusedException e) {
1573: logger
1574: .warn("buildAddCitationsPanelContext unable to access citationCollection "
1575: + collectionId);
1576: }
1577: if (collection == null) {
1578: logger
1579: .warn("buildAddCitationsPanelContext unable to access citationCollection "
1580: + collectionId);
1581: }
1582:
1583: String[] args = new String[] { Integer.toString(collection
1584: .size()) };
1585: String size_str = rb
1586: .getFormattedMessage("citation.count", args);
1587: pipe.setRevisedResourceProperty(
1588: ResourceProperties.PROP_CONTENT_LENGTH, size_str);
1589:
1590: // leave helper mode
1591: pipe.setActionCanceled(false);
1592: pipe.setErrorEncountered(false);
1593: pipe.setActionCompleted(true);
1594:
1595: toolSession.setAttribute(ResourceToolAction.DONE, Boolean.TRUE);
1596:
1597: cleanup(toolSession, CitationHelper.CITATION_PREFIX);
1598:
1599: } // doFinish
1600:
1601: /**
1602: * Cancel the action for which the helper was launched.
1603: */
1604: public void doCancel(RunData data) {
1605: ToolSession toolSession = SessionManager
1606: .getCurrentToolSession();
1607: ResourceToolActionPipe pipe = (ResourceToolActionPipe) toolSession
1608: .getAttribute(ResourceToolAction.ACTION_PIPE);
1609:
1610: if (pipe.getAction().getActionType() == ResourceToolAction.ActionType.CREATE) {
1611: SessionState state = ((JetspeedRunData) data)
1612: .getPortletSessionState(((JetspeedRunData) data)
1613: .getJs_peid());
1614: // TODO: delete the citation collection and all citations
1615:
1616: // TODO: delete the temporary resource
1617: String temporaryResourceId = (String) state
1618: .getAttribute(CitationHelper.RESOURCE_ID);
1619: ContentHostingService contentService = (ContentHostingService) ComponentManager
1620: .get("org.sakaiproject.content.api.ContentHostingService");
1621: ContentResourceEdit edit = null;
1622: try {
1623: edit = contentService.editResource(temporaryResourceId);
1624: contentService.removeResource(edit);
1625: edit = null;
1626: } catch (PermissionException e) {
1627: // TODO Auto-generated catch block
1628: logger.warn("PermissionException ", e);
1629: } catch (IdUnusedException e) {
1630: // TODO Auto-generated catch block
1631: logger.warn("IdUnusedException ", e);
1632: } catch (TypeException e) {
1633: // TODO Auto-generated catch block
1634: logger.warn("TypeException ", e);
1635: } catch (InUseException e) {
1636: // TODO Auto-generated catch block
1637: logger.warn("InUseException ", e);
1638: }
1639:
1640: if (edit != null) {
1641: contentService.cancelResource(edit);
1642: }
1643: }
1644:
1645: // leave helper mode
1646: pipe.setActionCanceled(true);
1647: pipe.setErrorEncountered(false);
1648: pipe.setActionCompleted(true);
1649:
1650: toolSession.setAttribute(ResourceToolAction.DONE, Boolean.TRUE);
1651:
1652: cleanup(toolSession, CitationHelper.CITATION_PREFIX);
1653:
1654: }
1655:
1656: /**
1657: * Adds a citation to the current citation collection. Called from the search-results popup.
1658: */
1659: public void doAddCitation(RunData data) {
1660: // get the state object
1661: SessionState state = ((JetspeedRunData) data)
1662: .getPortletSessionState(((JetspeedRunData) data)
1663: .getJs_peid());
1664: ParameterParser params = data.getParameters();
1665:
1666: // get the citation from search results, add it to the citation collection, and rebuild the context
1667: String[] citationIds = params.getStrings("citationId");
1668: String collectionId = params.getString("collectionId");
1669:
1670: Integer page = (Integer) state.getAttribute(STATE_LIST_PAGE);
1671: ActiveSearch search = (ActiveSearch) state
1672: .getAttribute(STATE_SEARCH_RESULTS);
1673: CitationCollection tempCollection = search.getSearchResults();
1674: Map index = search.getIndex();
1675: if (index == null) {
1676: index = new Hashtable();
1677: search.setIndex(index);
1678: }
1679:
1680: try {
1681: CitationCollection permCollection = CitationService
1682: .getCollection(collectionId);
1683: for (int i = 0; i < citationIds.length; i++) {
1684: try {
1685: Citation citation = tempCollection
1686: .getCitation(citationIds[i]);
1687: citation.setAdded(true);
1688: permCollection.add(citation);
1689: } catch (IdUnusedException ex) {
1690: logger.info("doAdd: unable to add citation "
1691: + citationIds[i] + " to collection "
1692: + collectionId);
1693: }
1694: }
1695: CitationService.save(permCollection);
1696: // setMode(state, Mode.LIST);
1697: } catch (IdUnusedException e) {
1698: logger.info("doAdd: unable to get collection "
1699: + collectionId);
1700: }
1701: }
1702:
1703: /**
1704: * @param data
1705: */
1706: public void doBack(RunData data) {
1707: // get the state object
1708: SessionState state = ((JetspeedRunData) data)
1709: .getPortletSessionState(((JetspeedRunData) data)
1710: .getJs_peid());
1711:
1712: popMode(state);
1713: }
1714:
1715: /**
1716: * @param state
1717: */
1718: protected void popMode(SessionState state) {
1719: Stack<Mode> stack = (Stack<Mode>) state
1720: .getAttribute(STATE_BACK_BUTTON_STACK);
1721:
1722: if (stack != null && stack.size() > 1) {
1723: // pop the Mode currently being viewed
1724: stack.pop();
1725:
1726: // pop the previous Mode - the one to go back to
1727: Mode mode = stack.pop();
1728: logger.debug("popMode popped " + mode);
1729:
1730: state.setAttribute(CitationHelper.STATE_HELPER_MODE, mode);
1731: } else {
1732: // stack should not be null or < 2
1733: logger
1734: .warn("popMode() getting null or < 2 back-button stack from state.");
1735: }
1736: }
1737:
1738: /**
1739: * Removes a citation from the current citation collection. Called from the search-results popup.
1740: */
1741: public void doRemove(RunData data) {
1742: // get the state object
1743: SessionState state = ((JetspeedRunData) data)
1744: .getPortletSessionState(((JetspeedRunData) data)
1745: .getJs_peid());
1746: ParameterParser params = data.getParameters();
1747:
1748: // get the citation number from search results, remove it from the citation collection, and rebuild the context
1749: // get the citation from search results, add it to the citation collection, and rebuild the context
1750: String[] citationIds = params.getStrings("citationId");
1751: String collectionId = params.getString("collectionId");
1752:
1753: ActiveSearch search = (ActiveSearch) state
1754: .getAttribute(STATE_SEARCH_RESULTS);
1755: CitationCollection tempCollection = search.getSearchResults();
1756: Map index = search.getIndex();
1757: if (index == null) {
1758: index = new Hashtable();
1759: search.setIndex(index);
1760: }
1761:
1762: try {
1763: CitationCollection permCollection = CitationService
1764: .getCollection(collectionId);
1765: for (int i = 0; i < citationIds.length; i++) {
1766: try {
1767: Citation citation = tempCollection
1768: .getCitation(citationIds[i]);
1769: citation.setAdded(false);
1770: permCollection.remove(citation);
1771: } catch (IdUnusedException ex) {
1772: logger.info("doAdd: unable to add citation "
1773: + citationIds[i] + " to collection "
1774: + collectionId);
1775: }
1776: }
1777: CitationService.save(permCollection);
1778: setMode(state, Mode.LIST);
1779: } catch (IdUnusedException e) {
1780: logger.info("doAdd: unable to get collection "
1781: + collectionId);
1782: }
1783: }
1784:
1785: public void doDatabasePopulate(RunData data) {
1786: SessionState state = ((JetspeedRunData) data)
1787: .getPortletSessionState(((JetspeedRunData) data)
1788: .getJs_peid());
1789: ParameterParser params = data.getParameters();
1790:
1791: // get category id
1792: String categoryId = params.get("categoryId");
1793: logger.debug("doDatabasePopulate() categoryId from URL: "
1794: + categoryId);
1795:
1796: if (categoryId == null) {
1797: // should not be null
1798: setMode(state, Mode.ERROR);
1799: return;
1800: } else {
1801: /* TODO can probably do this in build-method (don't need category in state)*/
1802: // get selected category, put it in state
1803: SearchDatabaseHierarchy hierarchy = (SearchDatabaseHierarchy) state
1804: .getAttribute(STATE_SEARCH_HIERARCHY);
1805:
1806: SearchCategory category = hierarchy.getCategory(categoryId);
1807: state.setAttribute(STATE_SELECTED_CATEGORY, category);
1808:
1809: setMode(state, Mode.DATABASE);
1810: }
1811: }
1812:
1813: /**
1814: *
1815: */
1816: public void doCreate(RunData data) {
1817: // get the state object
1818: SessionState state = ((JetspeedRunData) data)
1819: .getPortletSessionState(((JetspeedRunData) data)
1820: .getJs_peid());
1821:
1822: setMode(state, Mode.CREATE);
1823: //state.setAttribute(CitationHelper.SPECIAL_HELPER_ID, CitationHelper.CITATION_ID);
1824:
1825: } // doCreate
1826:
1827: /**
1828: * Pushes a non-ignorable Mode onto the back-button stack within the given
1829: * state object. Checks toPush against ignoreModes Set.
1830: *
1831: * @param state this session's state with non-null back-button stack
1832: * @param toPush Mode to push on the stack
1833: */
1834: protected void pushMode(SessionState state, Mode toPush) {
1835: // get stack from state
1836: Stack<Mode> stack = (Stack<Mode>) state
1837: .getAttribute(STATE_BACK_BUTTON_STACK);
1838:
1839: // (assuming stack is not null)
1840: // push only if toPush is not in ignoreModes and is not at the top of
1841: // the stack (a Mode should not be adjacent to itself)
1842: if (ignoreModes.contains(toPush)) {
1843: return;
1844: }
1845:
1846: if (stack.size() > 0 && stack.peek().equals(toPush)) {
1847: return;
1848: }
1849:
1850: stack.push(toPush);
1851: logger.debug("pushMode pushed " + toPush);
1852:
1853: // put this stack back into state
1854: state.setAttribute(STATE_BACK_BUTTON_STACK, stack);
1855: }
1856:
1857: /**
1858: * @param state
1859: * @param new_mode
1860: */
1861: protected void setMode(SessionState state, Mode new_mode) {
1862: Stack<Mode> stack = (Stack<Mode>) state
1863: .getAttribute(STATE_BACK_BUTTON_STACK);
1864: if (stack == null) {
1865: /* first time setMode has been called */
1866:
1867: // create a new Stack
1868: stack = new Stack<Mode>();
1869:
1870: // add to state
1871: state.setAttribute(STATE_BACK_BUTTON_STACK, stack);
1872:
1873: // add the previous mode (if any) to the stack
1874: Mode previous_mode = (Mode) state
1875: .getAttribute(CitationHelper.STATE_HELPER_MODE);
1876: if (previous_mode != null) {
1877: pushMode(state, previous_mode);
1878: }
1879: }
1880:
1881: // push newly selected Mode on the stack
1882: pushMode(state, new_mode);
1883:
1884: // set state attributes
1885: state.setAttribute(CitationHelper.STATE_HELPER_MODE, new_mode);
1886: state.setAttribute(STATE_BACK_BUTTON_STACK, stack);
1887: }
1888:
1889: /**
1890: *
1891: */
1892: public void doCreateCitation(RunData data) {
1893: // get the state object and the parameter parser
1894: SessionState state = ((JetspeedRunData) data)
1895: .getPortletSessionState(((JetspeedRunData) data)
1896: .getJs_peid());
1897: ParameterParser params = data.getParameters();
1898:
1899: Set validPropertyNames = CitationService
1900: .getValidPropertyNames();
1901: String mediatype = params.getString("type");
1902:
1903: CitationCollection collection = null;
1904:
1905: String collectionId = params.getString("collectionId");
1906:
1907: if (collectionId == null) {
1908: collectionId = (String) (String) state
1909: .getAttribute(STATE_COLLECTION_ID);
1910: }
1911: if (collectionId == null) {
1912: // log error and go on
1913: logger
1914: .info("CitationHelperAction.doCreateCitation no collection-id is given (creating new collection");
1915: collection = CitationService.addCollection();
1916: collectionId = collection.getId();
1917: state.setAttribute(STATE_COLLECTION_ID, collectionId);
1918: } else {
1919: try {
1920: collection = CitationService
1921: .getCollection(collectionId);
1922: } catch (IdUnusedException e) {
1923: // log error and go on
1924: logger
1925: .info("CitationHelperAction.doCreateCitation unable to retrieve collection (creating new collection");
1926: collection = CitationService.addCollection();
1927: collectionId = collection.getId();
1928: state.setAttribute(STATE_COLLECTION_ID, collectionId);
1929: }
1930: }
1931:
1932: // create a citation
1933: Citation citation = CitationService.addCitation(mediatype);
1934:
1935: updateCitationFromParams(citation, params);
1936:
1937: // add citation to current collection
1938: collection.add(citation);
1939: CitationService.save(collection);
1940:
1941: // call buildListPanelContext to show updated list
1942: //state.setAttribute(CitationHelper.SPECIAL_HELPER_ID, CitationHelper.CITATION_ID);
1943: setMode(state, Mode.LIST);
1944:
1945: } // doCreateCitation
1946:
1947: /**
1948: * @param citation
1949: * @param params
1950: */
1951: protected void updateCitationFromParams(Citation citation,
1952: ParameterParser params) {
1953: Schema schema = citation.getSchema();
1954:
1955: List fields = schema.getFields();
1956: Iterator fieldIt = fields.iterator();
1957: while (fieldIt.hasNext()) {
1958: Field field = (Field) fieldIt.next();
1959: String name = field.getIdentifier();
1960: if (field.isMultivalued()) {
1961: List values = new Vector();
1962:
1963: String count = params.getString(name + "_count");
1964: int num = 10;
1965: try {
1966: num = Integer.parseInt(count);
1967: for (int i = 0; i < num; i++) {
1968: String value = params.getString(name + i);
1969: if (value != null && !values.contains(value)) {
1970: values.add(value);
1971: }
1972: }
1973: citation.updateCitationProperty(name, values);
1974: } catch (NumberFormatException e) {
1975:
1976: }
1977: } else {
1978: String value = params.getString(name);
1979: citation.setCitationProperty(name, value);
1980: if (name.equals(Schema.TITLE)) {
1981: citation.setDisplayName(value);
1982: }
1983: }
1984: }
1985:
1986: int urlCount = 0;
1987: try {
1988: urlCount = params.getInt("url_count");
1989: } catch (Exception e) {
1990: logger
1991: .debug("doCreateCitation: unable to parse int for urlCount");
1992: }
1993:
1994: for (int i = 0; i < urlCount; i++) {
1995: String label = params.getString("label_" + i);
1996:
1997: String url = params.getString("url_" + i);
1998:
1999: String urlid = params.getString("urlid_" + i);
2000:
2001: if (url == null) {
2002: logger.debug("doCreateCitation: url null? " + url);
2003: } else {
2004: try {
2005: url = validateURL(url);
2006: } catch (MalformedURLException e) {
2007: logger
2008: .debug("doCreateCitation: unable to validate URL: "
2009: + url);
2010: continue;
2011: }
2012: }
2013:
2014: if (label == null || url == null) {
2015: logger.debug("doCreateCitation: label null? " + label
2016: + " url null? " + url);
2017: continue;
2018: } else if (urlid == null || urlid.trim().equals("")) {
2019: citation.addCustomUrl(label, url);
2020: } else {
2021: citation.updateCustomUrl(urlid, label, url);
2022: }
2023: }
2024: }
2025:
2026: /**
2027: *
2028: */
2029: public void doEdit(RunData data) {
2030: // get the state object
2031: SessionState state = ((JetspeedRunData) data)
2032: .getPortletSessionState(((JetspeedRunData) data)
2033: .getJs_peid());
2034: ParameterParser params = data.getParameters();
2035:
2036: String citationId = params.getString("citationId");
2037: String collectionId = params.getString("collectionId");
2038:
2039: CitationCollection collection = null;
2040: if (collectionId == null) {
2041: collectionId = (String) state
2042: .getAttribute(STATE_COLLECTION_ID);
2043: }
2044:
2045: if (collectionId == null) {
2046:
2047: } else {
2048: try {
2049: collection = CitationService
2050: .getCollection(collectionId);
2051: } catch (IdUnusedException e) {
2052: // must find a different way to get it
2053: }
2054:
2055: }
2056: if (collection == null) {
2057: collection = CitationService.addCollection();
2058: state.setAttribute(STATE_COLLECTION_ID, collection.getId());
2059: }
2060:
2061: Citation citation = null;
2062: try {
2063: citation = collection.getCitation(citationId);
2064: } catch (IdUnusedException e) {
2065: // add an alert (below)
2066: }
2067:
2068: if (citation == null) {
2069: addAlert(state, rb.getString("alert.access"));
2070: } else {
2071: state.setAttribute(CitationHelper.CITATION_EDIT_ID,
2072: citationId);
2073: state.setAttribute(CitationHelper.CITATION_EDIT_ITEM,
2074: citation);
2075: setMode(state, Mode.EDIT);
2076: }
2077:
2078: } // doEdit
2079:
2080: /**
2081: *
2082: */
2083: public void doList(RunData data) {
2084: // get the state object
2085: SessionState state = ((JetspeedRunData) data)
2086: .getPortletSessionState(((JetspeedRunData) data)
2087: .getJs_peid());
2088:
2089: setMode(state, Mode.LIST);
2090:
2091: } // doList
2092:
2093: public void doResults(RunData data) {
2094: // get the state object
2095: SessionState state = ((JetspeedRunData) data)
2096: .getPortletSessionState(((JetspeedRunData) data)
2097: .getJs_peid());
2098:
2099: setMode(state, Mode.RESULTS);
2100: }
2101:
2102: /**
2103: *
2104: */
2105: public void doAddCitations(RunData data) {
2106: // get the state object
2107: SessionState state = ((JetspeedRunData) data)
2108: .getPortletSessionState(((JetspeedRunData) data)
2109: .getJs_peid());
2110:
2111: setMode(state, Mode.ADD_CITATIONS);
2112:
2113: } // doAddCitations
2114:
2115: public void doMessageFrame(RunData data) {
2116: // get the state object
2117: SessionState state = ((JetspeedRunData) data)
2118: .getPortletSessionState(((JetspeedRunData) data)
2119: .getJs_peid());
2120: ParameterParser params = data.getParameters();
2121:
2122: // get params
2123: String citationId = params.getString("citationId");
2124: String collectionId = params.getString("collectionId");
2125: String operation = params.getString("operation");
2126:
2127: // check params
2128: if (operation == null) {
2129: logger.warn("doMessageFrame() 'operation' null argument");
2130: setMode(state, Mode.ERROR);
2131: return;
2132: }
2133:
2134: if (operation.trim().equalsIgnoreCase("refreshCount")) {
2135: // do not need to do anything, let buildMessagePanelContext update
2136: // count for citations
2137: setMode(state, Mode.MESSAGE);
2138: return;
2139: }
2140:
2141: if (operation == null || citationId == null
2142: || collectionId == null) {
2143: logger.warn("doMessageFrame() null argument - operation: "
2144: + operation + ", citationId: " + citationId + ", "
2145: + "collectionId: " + collectionId);
2146: setMode(state, Mode.ERROR);
2147: return;
2148: }
2149:
2150: // get Citation using citationId
2151: List<Citation> currentResults = (List<Citation>) state
2152: .getAttribute(STATE_CURRENT_RESULTS);
2153: Citation citation = null;
2154: for (Citation c : currentResults) {
2155: if (c.getId().equals(citationId)) {
2156: citation = c;
2157: break;
2158: }
2159: }
2160:
2161: if (citation == null) {
2162: logger.warn("doMessageFrame() bad citationId: "
2163: + citationId);
2164: setMode(state, Mode.ERROR);
2165: return;
2166: }
2167:
2168: // get CitationCollection using collectionId
2169: CitationCollection collection = null;
2170: try {
2171: collection = CitationService.getCollection(collectionId);
2172: } catch (IdUnusedException e) {
2173: logger
2174: .warn("doMessageFrame() unable to access citationCollection "
2175: + collectionId);
2176: }
2177: if (collection == null) {
2178: logger
2179: .warn("doMessageFrame() unable to access citationCollection "
2180: + collectionId);
2181: }
2182:
2183: // do operation
2184: if (operation.equalsIgnoreCase("add")) {
2185: logger.info("adding citation " + citationId + " to "
2186: + collectionId);
2187: citation.setAdded(true);
2188: collection.add(citation);
2189: CitationService.save(collection);
2190: } else if (operation.equalsIgnoreCase("remove")) {
2191: logger.info("removing citation " + citationId + " from "
2192: + collectionId);
2193: collection.remove(citation);
2194: citation.setAdded(false);
2195: CitationService.save(collection);
2196: } else {
2197: // do nothing
2198: logger.info("null operation: " + operation);
2199: }
2200:
2201: // store the citation's new id to send back to UI
2202: state.setAttribute(STATE_CITATION_ID, citation.getId());
2203:
2204: setMode(state, Mode.MESSAGE);
2205: }
2206:
2207: public void doRemoveAllCitations(RunData data) {
2208: // get the state object
2209: SessionState state = ((JetspeedRunData) data)
2210: .getPortletSessionState(((JetspeedRunData) data)
2211: .getJs_peid());
2212: ParameterParser params = data.getParameters();
2213:
2214: String collectionId = params.getString("collectionId");
2215:
2216: CitationCollection collection = null;
2217:
2218: if (collectionId == null) {
2219: collectionId = (String) state
2220: .getAttribute(STATE_COLLECTION_ID);
2221: }
2222: if (collectionId == null) {
2223: // TODO add alert and log error
2224: } else {
2225: try {
2226: collection = CitationService
2227: .getCollection(collectionId);
2228: } catch (IdUnusedException e) {
2229: // TODO add alert and log error
2230: logger
2231: .warn("CitationHelperAction.doRemoveCitation unable to retrieve collection: "
2232: + collectionId);
2233: }
2234: }
2235:
2236: if (collection == null) {
2237: // TODO add alert and log error
2238: logger
2239: .warn("CitationHelperAction.doRemoveCitation collection null: "
2240: + collectionId);
2241: } else {
2242: // remove all citations
2243: List<Citation> citations = collection.getCitations();
2244:
2245: if (citations != null && citations.size() > 0) {
2246: for (Citation citation : citations) {
2247: collection.remove(citation);
2248: }
2249: CitationService.save(collection);
2250: }
2251: }
2252:
2253: setMode(state, Mode.LIST);
2254:
2255: } // doRemoveAllCitations
2256:
2257: public void doRemoveSelectedCitations(RunData data) {
2258: // get the state object
2259: SessionState state = ((JetspeedRunData) data)
2260: .getPortletSessionState(((JetspeedRunData) data)
2261: .getJs_peid());
2262: ParameterParser params = data.getParameters();
2263:
2264: String collectionId = params.getString("collectionId");
2265:
2266: CitationCollection collection = null;
2267:
2268: if (collectionId == null) {
2269: collectionId = (String) state
2270: .getAttribute(STATE_COLLECTION_ID);
2271: }
2272: if (collectionId == null) {
2273: // TODO add alert and log error
2274: } else {
2275: try {
2276: collection = CitationService
2277: .getCollection(collectionId);
2278: } catch (IdUnusedException e) {
2279: // TODO add alert and log error
2280: logger
2281: .warn("doRemoveSelectedCitation() unable to retrieve collection: "
2282: + collectionId);
2283: }
2284: }
2285:
2286: if (collection == null) {
2287: // TODO add alert and log error
2288: logger.warn("doRemoveSelectedCitation() collection null: "
2289: + collectionId);
2290: } else {
2291: // remove selected citations
2292: String[] paramCitationIds = params.getStrings("citationId");
2293: if (paramCitationIds != null && paramCitationIds.length > 0) {
2294: List<String> citationIds = new java.util.ArrayList<String>();
2295: citationIds.addAll(Arrays.asList(paramCitationIds));
2296:
2297: try {
2298: for (String citationId : citationIds) {
2299: Citation citation = collection
2300: .getCitation(citationId);
2301: collection.remove(citation);
2302: }
2303: CitationService.save(collection);
2304: } catch (IdUnusedException e) {
2305: logger
2306: .warn(
2307: "doRemoveSelectedCitation() unable to get and remove citation",
2308: e);
2309: }
2310: }
2311: }
2312:
2313: state.setAttribute(STATE_LIST_NO_SCROLL, Boolean.TRUE);
2314: setMode(state, Mode.LIST);
2315:
2316: } // doRemoveSelectedCitations
2317:
2318: /**
2319: *
2320: */
2321: public void doReviseCitation(RunData data) {
2322: // get the state object and the parameter parser
2323: SessionState state = ((JetspeedRunData) data)
2324: .getPortletSessionState(((JetspeedRunData) data)
2325: .getJs_peid());
2326: ParameterParser params = data.getParameters();
2327:
2328: // Set validPropertyNames = CitationService.getValidPropertyNames();
2329: // String mediatype = params.getString("type");
2330:
2331: CitationCollection collection = null;
2332: Citation citation = null;
2333:
2334: String collectionId = (String) state
2335: .getAttribute(STATE_COLLECTION_ID);
2336: String citationId = (String) state
2337: .getAttribute(CitationHelper.CITATION_EDIT_ID);
2338:
2339: if (collectionId == null) {
2340: collection = CitationService.addCollection();
2341: state.setAttribute(STATE_COLLECTION_ID, collection.getId());
2342: collectionId = collection.getId();
2343: } else {
2344: try {
2345: collection = CitationService
2346: .getCollection(collectionId);
2347: } catch (IdUnusedException e) {
2348: logger
2349: .warn("CitationHelperAction.doReviseCitation unable to get collection");
2350: }
2351: }
2352:
2353: if (collection == null) {
2354: // TODO add alert and log error
2355: } else {
2356: try {
2357: citation = collection.getCitation(citationId);
2358:
2359: String schemaId = params.getString("type");
2360: Schema schema = CitationService.getSchema(schemaId);
2361: citation.setSchema(schema);
2362:
2363: updateCitationFromParams(citation, params);
2364:
2365: // add citation to current collection
2366: collection.saveCitation(citation);
2367: } catch (IdUnusedException e) {
2368: // TODO add alert and log error
2369: }
2370:
2371: CitationService.save(collection);
2372: }
2373:
2374: setMode(state, Mode.LIST);
2375:
2376: } // doReviseCitation
2377:
2378: /**
2379: *
2380: * @param data
2381: */
2382: public void doCancelSearch(RunData data) {
2383: // get state and params
2384: SessionState state = ((JetspeedRunData) data)
2385: .getPortletSessionState(((JetspeedRunData) data)
2386: .getJs_peid());
2387:
2388: // cancel the running search
2389: ActiveSearch search = (ActiveSearch) state
2390: .getAttribute(STATE_SEARCH_INFO);
2391: if (search != null) {
2392: Thread searchThread = search.getSearchThread();
2393: if (searchThread != null) {
2394: try {
2395: searchThread.interrupt();
2396: } catch (SecurityException se) {
2397: // not able to interrupt search
2398: logger
2399: .warn("doSearch() [in ThreadGroup "
2400: + Thread.currentThread()
2401: .getThreadGroup().getName()
2402: + "] unable to interrupt search Thread [name="
2403: + searchThread.getName()
2404: + ", id="
2405: + searchThread.getId()
2406: + ", group="
2407: + searchThread.getThreadGroup()
2408: .getName() + "]");
2409: }
2410: }
2411: }
2412:
2413: // default return to search page
2414: setMode(state, Mode.SEARCH);
2415:
2416: } // doCancelSearch
2417:
2418: /**
2419: *
2420: */
2421: public void doSearch(RunData data) {
2422: // get the state object
2423: SessionState state = ((JetspeedRunData) data)
2424: .getPortletSessionState(((JetspeedRunData) data)
2425: .getJs_peid());
2426:
2427: // remove attributes from an old search session, if any
2428: state.removeAttribute(STATE_SEARCH_RESULTS);
2429: state.removeAttribute(STATE_CURRENT_RESULTS);
2430: state.removeAttribute(STATE_KEYWORDS);
2431:
2432: // indicate a basic search
2433: state.setAttribute(STATE_BASIC_SEARCH, new Object());
2434:
2435: try {
2436: SearchDatabaseHierarchy hierarchy = SearchManager
2437: .getSearchHierarchy();
2438: if (hierarchy == null) {
2439: addAlert(state, rb.getString("search.problem"));
2440: setMode(state, Mode.ERROR);
2441: return;
2442: }
2443:
2444: state.setAttribute(STATE_SEARCH_HIERARCHY, hierarchy);
2445:
2446: setMode(state, Mode.SEARCH);
2447: } catch (SearchException e) {
2448: // addAlert(state, rb.getString("search.problem"));
2449: addAlert(state, e.getMessage());
2450: setMode(state, Mode.ERROR);
2451: }
2452:
2453: } // doSearch
2454:
2455: /**
2456: *
2457: */
2458: public void doBeginSearch(RunData data) {
2459: // get state and params
2460: SessionState state = ((JetspeedRunData) data)
2461: .getPortletSessionState(((JetspeedRunData) data)
2462: .getJs_peid());
2463: ParameterParser params = data.getParameters();
2464:
2465: // get search object from state
2466: ActiveSearch search = (ActiveSearch) state
2467: .getAttribute(STATE_SEARCH_INFO);
2468: if (search == null) {
2469: logger
2470: .debug("doBeginSearch() got null ActiveSearch from state.");
2471: search = SearchManager.newSearch();
2472: }
2473:
2474: // get databases selected
2475: String[] databaseIds = params.getStrings("databasesSelected");
2476: logger.debug("Databases selected:");
2477: for (String databaseId : databaseIds) {
2478: logger.debug(" " + databaseId);
2479: }
2480:
2481: // check the databases to make sure they are indeed searchable by this user
2482: if (databaseIds != null) {
2483: SearchDatabaseHierarchy hierarchy = (SearchDatabaseHierarchy) state
2484: .getAttribute(STATE_SEARCH_HIERARCHY);
2485: for (int i = 0; i < databaseIds.length; i++) {
2486: if (!hierarchy.isSearchableDatabase(databaseIds[i])) {
2487: // TODO collect a list of the databases which are
2488: // not searchable and pass them to the UI
2489:
2490: // do not search if databases selected
2491: // are not searchable by this user
2492: state.setAttribute(STATE_UNAUTHORIZED_DB,
2493: Boolean.TRUE);
2494: logger
2495: .warn("doBeginSearch() unauthorized database: "
2496: + databaseIds[i]);
2497: setMode(state, Mode.RESULTS);
2498: return;
2499: }
2500: }
2501:
2502: // databases are searchable
2503: SearchManager.setDatabaseIds(databaseIds);
2504: state.setAttribute(STATE_CURRENT_DATABASES, databaseIds);
2505: } else {
2506: // no databases selected, cannot continue
2507: state.setAttribute(STATE_NO_DATABASES, Boolean.TRUE);
2508: setMode(state, Mode.RESULTS);
2509: return;
2510: }
2511:
2512: /*
2513: * do basic/advanced search-specific processing
2514: */
2515: // determine which type of search has been issued
2516: String searchType = params.getString("searchType");
2517: if (searchType != null
2518: && searchType
2519: .equalsIgnoreCase(ActiveSearch.ADVANCED_SEARCH_TYPE)) {
2520: doAdvancedSearch(params, state, search);
2521: } else {
2522: doBasicSearch(params, state, search);
2523: }
2524:
2525: /*
2526: * BEGIN SEARCH
2527: */
2528: try {
2529: // set search thread to the current thread
2530: search.setSearchThread(Thread.currentThread());
2531: state.setAttribute(STATE_SEARCH_INFO, search);
2532:
2533: // initiate the search
2534: List latestResults = search.viewPage();
2535: String msg = search.getStatusMessage();
2536: if (msg != null) {
2537: addAlert(state, msg);
2538: search.setStatusMessage();
2539: }
2540:
2541: if (latestResults != null) {
2542: state.setAttribute(STATE_SEARCH_RESULTS, search);
2543: state
2544: .setAttribute(STATE_CURRENT_RESULTS,
2545: latestResults);
2546: setMode(state, Mode.RESULTS);
2547: } else {
2548: // the search has been canceled - determine which page should
2549: // be reloaded
2550: String cancel = params.getString("cancelOp");
2551: if (cancel != null && !cancel.trim().equals("")) {
2552: if (cancel
2553: .equalsIgnoreCase(ELEMENT_ID_RESULTS_FORM)) {
2554: setMode(state, Mode.RESULTS);
2555: } else {
2556: setMode(state, Mode.SEARCH);
2557: }
2558: }
2559: }
2560: } catch (Exception e) {
2561: logger.warn("doBeginSearch() caught Exception", e);
2562: state.setAttribute(STATE_NO_RESULTS, Boolean.TRUE);
2563: setMode(state, Mode.RESULTS);
2564: return;
2565: }
2566:
2567: ActiveSearch newSearch = SearchManager.newSearch();
2568: state.setAttribute(STATE_SEARCH_INFO, newSearch);
2569:
2570: } // doBeginSearch
2571:
2572: /**
2573: * Sets up a basic search.
2574: *
2575: * @param params request parameters from doBeginSearch
2576: * @param state session state
2577: * @param search current search
2578: */
2579: protected void doBasicSearch(ParameterParser params,
2580: SessionState state, ActiveSearch search) {
2581: // signal a basic search
2582: state.setAttribute(STATE_BASIC_SEARCH, new Object());
2583: search.setSearchType(ActiveSearch.BASIC_SEARCH_TYPE);
2584:
2585: // get keywords
2586: String keywords = params.getString("keywords");
2587: if (keywords == null || keywords.trim().equals("")) {
2588: logger.warn("doBasicSearch() getting null/empty keywords");
2589: }
2590:
2591: // set up search query
2592: SearchQuery basicQuery = new org.sakaiproject.citation.util.impl.SearchQuery();
2593: basicQuery.addKeywords(keywords);
2594:
2595: // set query for this search
2596: search.setBasicQuery(basicQuery);
2597:
2598: // save state
2599: state.setAttribute(STATE_KEYWORDS, keywords);
2600:
2601: } // doBasicSearch
2602:
2603: /**
2604: * Sets up an advanced search.
2605: *
2606: * @param params request parameters from doBeginSearch
2607: * @param state session state
2608: * @param search current search
2609: */
2610: protected void doAdvancedSearch(ParameterParser params,
2611: SessionState state, ActiveSearch search) {
2612: // signal an advanced search
2613: state.removeAttribute(STATE_BASIC_SEARCH);
2614: search.setSearchType(ActiveSearch.ADVANCED_SEARCH_TYPE);
2615:
2616: // clear old state
2617: AdvancedSearchHelper.clearAdvancedFormState(state);
2618:
2619: // set selected fields
2620: AdvancedSearchHelper.setFieldSelections(params, state);
2621:
2622: // set entered criteria
2623: AdvancedSearchHelper.setFieldCriteria(params, state);
2624:
2625: // get a Map of advancedCritera for the search
2626: search.setAdvancedQuery(AdvancedSearchHelper
2627: .getAdvancedCriteria(state));
2628: }
2629:
2630: /**
2631: *
2632: */
2633: public void doNextListPage(RunData data) {
2634: // get the state object
2635: SessionState state = ((JetspeedRunData) data)
2636: .getPortletSessionState(((JetspeedRunData) data)
2637: .getJs_peid());
2638: // ParameterParser params = data.getParameters();
2639:
2640: CitationIterator listIterator = (CitationIterator) state
2641: .getAttribute(STATE_LIST_ITERATOR);
2642: if (listIterator == null) {
2643: CitationCollection collection = null;
2644: String collectionId = (String) state
2645: .getAttribute(STATE_COLLECTION_ID);
2646: if (collectionId == null) {
2647: collection = CitationService.addCollection();
2648: state.setAttribute(STATE_COLLECTION_ID, collection
2649: .getId());
2650: } else {
2651: try {
2652: collection = CitationService
2653: .getCollection(collectionId);
2654: } catch (IdUnusedException e) {
2655: logger
2656: .warn("CitationHelperAction.buildListPanelContext unable to access citationCollection "
2657: + collectionId);
2658: }
2659: if (collection == null) {
2660: collection = CitationService.addCollection();
2661: state.setAttribute(STATE_COLLECTION_ID, collection
2662: .getId());
2663: }
2664: }
2665: listIterator = collection.iterator();
2666: state.setAttribute(STATE_LIST_ITERATOR, listIterator);
2667: }
2668: if (listIterator.hasNextPage()) {
2669: listIterator.nextPage();
2670: }
2671:
2672: } // doNextListPage
2673:
2674: /**
2675: *
2676: */
2677: public void doPrevListPage(RunData data) {
2678: // get the state object
2679: SessionState state = ((JetspeedRunData) data)
2680: .getPortletSessionState(((JetspeedRunData) data)
2681: .getJs_peid());
2682: // ParameterParser params = data.getParameters();
2683:
2684: CitationIterator listIterator = (CitationIterator) state
2685: .getAttribute(STATE_LIST_ITERATOR);
2686: if (listIterator == null) {
2687: CitationCollection collection = null;
2688: String collectionId = (String) state
2689: .getAttribute(STATE_COLLECTION_ID);
2690: if (collectionId == null) {
2691: collection = CitationService.addCollection();
2692: state.setAttribute(STATE_COLLECTION_ID, collection
2693: .getId());
2694: } else {
2695: try {
2696: collection = CitationService
2697: .getCollection(collectionId);
2698: } catch (IdUnusedException e) {
2699: logger
2700: .warn("CitationHelperAction.buildListPanelContext unable to access citationCollection "
2701: + collectionId);
2702: }
2703: if (collection == null) {
2704: collection = CitationService.addCollection();
2705: state.setAttribute(STATE_COLLECTION_ID, collection
2706: .getId());
2707: }
2708: }
2709: listIterator = collection.iterator();
2710: state.setAttribute(STATE_LIST_ITERATOR, listIterator);
2711: }
2712: if (listIterator.hasPreviousPage()) {
2713: listIterator.previousPage();
2714: }
2715:
2716: } // doSearch
2717:
2718: /**
2719: *
2720: */
2721: public void doLastListPage(RunData data) {
2722: // get the state object
2723: SessionState state = ((JetspeedRunData) data)
2724: .getPortletSessionState(((JetspeedRunData) data)
2725: .getJs_peid());
2726: // ParameterParser params = data.getParameters();
2727:
2728: CitationCollection collection = null;
2729: String collectionId = (String) state
2730: .getAttribute(STATE_COLLECTION_ID);
2731: if (collectionId == null) {
2732: collection = CitationService.addCollection();
2733: state.setAttribute(STATE_COLLECTION_ID, collection.getId());
2734: } else {
2735: try {
2736: collection = CitationService
2737: .getCollection(collectionId);
2738: } catch (IdUnusedException e) {
2739: logger
2740: .warn("CitationHelperAction.buildListPanelContext unable to access citationCollection "
2741: + collectionId);
2742: }
2743: if (collection == null) {
2744: collection = CitationService.addCollection();
2745: state.setAttribute(STATE_COLLECTION_ID, collection
2746: .getId());
2747: }
2748: }
2749:
2750: CitationIterator listIterator = (CitationIterator) state
2751: .getAttribute(STATE_LIST_ITERATOR);
2752: if (listIterator == null) {
2753: listIterator = collection.iterator();
2754: state.setAttribute(STATE_LIST_ITERATOR, listIterator);
2755: }
2756:
2757: int pageSize = listIterator.getPageSize();
2758: int totalSize = collection.size();
2759: int lastPage = 0;
2760: if (totalSize > 0) {
2761: lastPage = (totalSize - 1) / pageSize;
2762: }
2763: listIterator.setPage(lastPage);
2764:
2765: } // doSearch
2766:
2767: /**
2768: *
2769: */
2770: public void doFirstListPage(RunData data) {
2771: // get the state object
2772: SessionState state = ((JetspeedRunData) data)
2773: .getPortletSessionState(((JetspeedRunData) data)
2774: .getJs_peid());
2775: // ParameterParser params = data.getParameters();
2776:
2777: CitationIterator listIterator = (CitationIterator) state
2778: .getAttribute(STATE_LIST_ITERATOR);
2779: if (listIterator == null) {
2780: CitationCollection collection = null;
2781: String collectionId = (String) state
2782: .getAttribute(STATE_COLLECTION_ID);
2783: if (collectionId == null) {
2784: collection = CitationService.addCollection();
2785: state.setAttribute(STATE_COLLECTION_ID, collection
2786: .getId());
2787: } else {
2788: try {
2789: collection = CitationService
2790: .getCollection(collectionId);
2791: } catch (IdUnusedException e) {
2792: logger
2793: .warn("CitationHelperAction.buildListPanelContext unable to access citationCollection "
2794: + collectionId);
2795: }
2796: if (collection == null) {
2797: collection = CitationService.addCollection();
2798: state.setAttribute(STATE_COLLECTION_ID, collection
2799: .getId());
2800: }
2801: }
2802:
2803: listIterator = collection.iterator();
2804: state.setAttribute(STATE_LIST_ITERATOR, listIterator);
2805: }
2806:
2807: listIterator.setPage(0);
2808:
2809: } // doSearch
2810:
2811: /**
2812: *
2813: */
2814: public void doNextSearchPage(RunData data) {
2815: // get the state object
2816: SessionState state = ((JetspeedRunData) data)
2817: .getPortletSessionState(((JetspeedRunData) data)
2818: .getJs_peid());
2819: // ParameterParser params = data.getParameters();
2820:
2821: ActiveSearch search = (ActiveSearch) state
2822: .getAttribute(STATE_SEARCH_RESULTS);
2823: if (search == null) {
2824: search = SearchManager.newSearch();
2825: }
2826: // search.prepareForNextPage();
2827:
2828: try {
2829: List latestResults = search.viewPage(search
2830: .getViewPageNumber() + 1);
2831: String msg = search.getStatusMessage();
2832: if (msg != null) {
2833: addAlert(state, msg);
2834: search.setStatusMessage();
2835: }
2836: state.setAttribute(STATE_CURRENT_RESULTS, latestResults);
2837: setMode(state, Mode.RESULTS);
2838: } catch (SearchException e) {
2839: logger.warn("doNextSearchPage: " + e.getMessage());
2840: addAlert(state, rb.getString("error.search"));
2841: setMode(state, Mode.RESULTS);
2842: } catch (Exception e) {
2843: logger.warn("doNextSearchPage: " + e.getMessage());
2844: }
2845:
2846: } // doSearch
2847:
2848: /**
2849: *
2850: */
2851: public void doPrevSearchPage(RunData data) {
2852: // get the state object
2853: SessionState state = ((JetspeedRunData) data)
2854: .getPortletSessionState(((JetspeedRunData) data)
2855: .getJs_peid());
2856: // ParameterParser params = data.getParameters();
2857:
2858: ActiveSearch search = (ActiveSearch) state
2859: .getAttribute(STATE_SEARCH_RESULTS);
2860: if (search == null) {
2861: search = SearchManager.newSearch();
2862: }
2863: // search.prepareForNextPage();
2864:
2865: try {
2866: List latestResults = search.viewPage(search
2867: .getViewPageNumber() - 1);
2868: String msg = search.getStatusMessage();
2869: if (msg != null) {
2870: addAlert(state, msg);
2871: search.setStatusMessage();
2872: }
2873: state.setAttribute(STATE_CURRENT_RESULTS, latestResults);
2874: setMode(state, Mode.RESULTS);
2875: } catch (SearchException e) {
2876: logger.warn("doPrevSearchPage: " + e.getMessage());
2877: addAlert(state, rb.getString("error.search"));
2878: setMode(state, Mode.RESULTS);
2879: } catch (Exception e) {
2880: logger.warn("doPrevSearchPage: " + e.getMessage());
2881: }
2882:
2883: } // doSearch
2884:
2885: /**
2886: *
2887: */
2888: public void doFirstSearchPage(RunData data) {
2889: // get the state object
2890: SessionState state = ((JetspeedRunData) data)
2891: .getPortletSessionState(((JetspeedRunData) data)
2892: .getJs_peid());
2893: // ParameterParser params = data.getParameters();
2894:
2895: ActiveSearch search = (ActiveSearch) state
2896: .getAttribute(STATE_SEARCH_RESULTS);
2897: if (search == null) {
2898: search = SearchManager.newSearch();
2899: }
2900: // search.prepareForNextPage();
2901:
2902: try {
2903: List latestResults = search.viewPage(0);
2904: String msg = search.getStatusMessage();
2905: if (msg != null) {
2906: addAlert(state, msg);
2907: search.setStatusMessage();
2908: }
2909: state.setAttribute(STATE_CURRENT_RESULTS, latestResults);
2910: setMode(state, Mode.RESULTS);
2911: } catch (SearchException e) {
2912: logger.warn("doFirstSearchPage: " + e.getMessage());
2913: addAlert(state, rb.getString("error.search"));
2914: setMode(state, Mode.RESULTS);
2915: } catch (Exception e) {
2916: logger.warn("doFirstSearchPage: " + e.getMessage());
2917: }
2918:
2919: } // doSearch
2920:
2921: /**
2922: *
2923: */
2924: public void doChangeSearchPageSize(RunData data) {
2925: // get the state object
2926: SessionState state = ((JetspeedRunData) data)
2927: .getPortletSessionState(((JetspeedRunData) data)
2928: .getJs_peid());
2929: ParameterParser params = data.getParameters();
2930:
2931: ActiveSearch search = (ActiveSearch) state
2932: .getAttribute(STATE_SEARCH_RESULTS);
2933: if (search == null) {
2934: search = SearchManager.newSearch();
2935: state.setAttribute(STATE_SEARCH_RESULTS, search);
2936: }
2937: // search.prepareForNextPage();
2938:
2939: // check for top or bottom page selector
2940: String pageSelector = params.get("pageSelector");
2941: int pageSize;
2942: if (pageSelector.equals("top")) {
2943: pageSize = params.getInt("pageSizeTop");
2944: } else {
2945: pageSize = params.getInt("pageSizeBottom");
2946: }
2947:
2948: if (pageSize > 0) {
2949: // use the new value
2950: } else {
2951: // use the old value
2952: pageSize = search.getViewPageSize();
2953: }
2954:
2955: state.setAttribute(STATE_RESULTS_PAGE_SIZE, new Integer(
2956: pageSize));
2957:
2958: try {
2959: int last = search.getLastRecordIndex();
2960: int page = (last - 1) / pageSize;
2961:
2962: search.setViewPageSize(pageSize);
2963: List latestResults = search.viewPage(page);
2964: String msg = search.getStatusMessage();
2965: if (msg != null) {
2966: addAlert(state, msg);
2967: search.setStatusMessage();
2968: }
2969: state.setAttribute(STATE_CURRENT_RESULTS, latestResults);
2970: setMode(state, Mode.RESULTS);
2971: } catch (SearchException e) {
2972: logger.warn("doChangeSearchPageSize: " + e.getMessage());
2973: addAlert(state, rb.getString("error.search"));
2974: setMode(state, Mode.RESULTS);
2975: } catch (Exception e) {
2976: logger.warn("doChangeSearchPageSize: " + e.getMessage());
2977: }
2978:
2979: } // doChangeSearchPageSize
2980:
2981: /**
2982: *
2983: */
2984: public void doChangeListPageSize(RunData data) {
2985: // get the state object
2986: SessionState state = ((JetspeedRunData) data)
2987: .getPortletSessionState(((JetspeedRunData) data)
2988: .getJs_peid());
2989: ParameterParser params = data.getParameters();
2990:
2991: // check for top or bottom page selector
2992: String pageSelector = params.get("pageSelector");
2993: int pageSize;
2994: if (pageSelector.equals("top")) {
2995: pageSize = params.getInt("pageSizeTop");
2996: } else {
2997: pageSize = params.getInt("pageSizeBottom");
2998: }
2999:
3000: if (pageSize > 0) {
3001: state.setAttribute(STATE_LIST_PAGE_SIZE, new Integer(
3002: pageSize));
3003: }
3004:
3005: } // doSearch
3006:
3007: /**
3008: *
3009: */
3010: public void doView(RunData data) {
3011: // get the state object
3012: SessionState state = ((JetspeedRunData) data)
3013: .getPortletSessionState(((JetspeedRunData) data)
3014: .getJs_peid());
3015: ParameterParser params = data.getParameters();
3016:
3017: String citationId = params.getString("citationId");
3018: String collectionId = params.getString("collectionId");
3019:
3020: CitationCollection collection = null;
3021: if (collectionId == null) {
3022: collectionId = (String) state
3023: .getAttribute(STATE_COLLECTION_ID);
3024: }
3025:
3026: if (collectionId == null) {
3027:
3028: } else {
3029: try {
3030: collection = CitationService
3031: .getCollection(collectionId);
3032: } catch (IdUnusedException e) {
3033: // must find a different way to get it
3034: }
3035:
3036: }
3037: if (collection == null) {
3038: addAlert(state, rb.getString("alert.access"));
3039: } else {
3040: Citation citation = null;
3041: try {
3042: citation = collection.getCitation(citationId);
3043: } catch (IdUnusedException e) {
3044: // add an alert (below)
3045: }
3046:
3047: if (citation == null) {
3048: addAlert(state, rb.getString("alert.access"));
3049: } else {
3050: state.setAttribute(CitationHelper.CITATION_VIEW_ID,
3051: citationId);
3052: state.setAttribute(CitationHelper.CITATION_VIEW_ITEM,
3053: citation);
3054: setMode(state, Mode.VIEW);
3055: }
3056: }
3057:
3058: } // doView
3059:
3060: protected void initHelper(VelocityPortlet portlet, Context context,
3061: RunData rundata, SessionState state) {
3062: ToolSession toolSession = SessionManager
3063: .getCurrentToolSession();
3064: ResourceToolActionPipe pipe = (ResourceToolActionPipe) toolSession
3065: .getAttribute(ResourceToolAction.ACTION_PIPE);
3066: // TODO: if not enterring as a helper, we will need to create pipe???
3067:
3068: if (pipe.isActionCompleted()) {
3069: return;
3070: }
3071:
3072: Mode mode = (Mode) state
3073: .getAttribute(CitationHelper.STATE_HELPER_MODE);
3074: if (mode == null) {
3075: switch (pipe.getAction().getActionType()) {
3076: case CREATE:
3077: ContentResource tempResource = createTemporaryResource(pipe);
3078: state.setAttribute(CitationHelper.RESOURCE_ID,
3079: tempResource.getId());
3080:
3081: String displayName = tempResource
3082: .getProperties()
3083: .getProperty(
3084: org.sakaiproject.entity.api.ResourceProperties.PROP_DISPLAY_NAME);
3085: state.setAttribute(STATE_COLLECTION_TITLE, displayName);
3086:
3087: try {
3088: state.setAttribute(STATE_COLLECTION_ID, new String(
3089: tempResource.getContent()));
3090: } catch (ServerOverloadException e) {
3091: logger.warn("ServerOverloadException ", e);
3092: }
3093: state.setAttribute(STATE_RESOURCES_ADD, Boolean.TRUE);
3094: setMode(state, Mode.ADD_CITATIONS);
3095: break;
3096: case REVISE_CONTENT:
3097: state.setAttribute(CitationHelper.RESOURCE_ID, pipe
3098: .getContentEntity().getId());
3099: try {
3100: state.setAttribute(STATE_COLLECTION_ID, new String(
3101: ((ContentResource) pipe.getContentEntity())
3102: .getContent()));
3103: } catch (ServerOverloadException e) {
3104: logger.warn("ServerOverloadException ", e);
3105: }
3106: state.removeAttribute(STATE_RESOURCES_ADD);
3107: setMode(state, Mode.LIST);
3108: break;
3109: default:
3110: break;
3111: }
3112: }
3113:
3114: if (state.getAttribute(STATE_RESULTS_PAGE_SIZE) == null) {
3115: state.setAttribute(STATE_RESULTS_PAGE_SIZE,
3116: DEFAULT_RESULTS_PAGE_SIZE);
3117: }
3118:
3119: if (state.getAttribute(STATE_LIST_PAGE_SIZE) == null) {
3120: state.setAttribute(STATE_LIST_PAGE_SIZE,
3121: DEFAULT_LIST_PAGE_SIZE);
3122: }
3123:
3124: } // initHelper
3125:
3126: /**
3127: *
3128: * @param pipe
3129: * @return
3130: */
3131: protected ContentResource createTemporaryResource(
3132: ResourceToolActionPipe pipe) {
3133: try {
3134: ContentHostingService contentService = (ContentHostingService) ComponentManager
3135: .get("org.sakaiproject.content.api.ContentHostingService");
3136: ContentResourceEdit newItem = contentService
3137: .addResource(
3138: pipe.getContentEntity().getId(),
3139: "New Citation List",
3140: null,
3141: ContentHostingService.MAXIMUM_ATTEMPTS_FOR_UNIQUENESS);
3142: newItem.setResourceType(CitationService.CITATION_LIST_ID);
3143: newItem.setContentType(ResourceType.MIME_TYPE_HTML);
3144: //newItem.setHidden();
3145:
3146: ResourcePropertiesEdit props = newItem.getPropertiesEdit();
3147:
3148: // set the alternative_reference to point to reference_root for CitationService
3149: props
3150: .addProperty(
3151: contentService.PROP_ALTERNATE_REFERENCE,
3152: org.sakaiproject.citation.api.CitationService.REFERENCE_ROOT);
3153: props.addProperty(ResourceProperties.PROP_CONTENT_TYPE,
3154: ResourceType.MIME_TYPE_HTML);
3155: props.addProperty(
3156: CitationService.PROP_TEMPORARY_CITATION_LIST,
3157: Boolean.TRUE.toString());
3158:
3159: CitationCollection collection = CitationService
3160: .addCollection();
3161: newItem.setContent(collection.getId().getBytes());
3162: newItem.setContentType(ResourceType.MIME_TYPE_HTML);
3163:
3164: contentService.commitResource(newItem,
3165: NotificationService.NOTI_NONE);
3166:
3167: return newItem;
3168: } catch (PermissionException e) {
3169: // TODO Auto-generated catch block
3170: logger.warn("PermissionException ", e);
3171: } catch (IdUniquenessException e) {
3172: // TODO Auto-generated catch block
3173: logger.warn("IdUniquenessException ", e);
3174: } catch (IdLengthException e) {
3175: // TODO Auto-generated catch block
3176: logger.warn("IdLengthException ", e);
3177: } catch (IdInvalidException e) {
3178: // TODO Auto-generated catch block
3179: logger.warn("IdInvalidException ", e);
3180: } catch (IdUnusedException e) {
3181: // TODO Auto-generated catch block
3182: logger.warn("IdUnusedException ", e);
3183: } catch (OverQuotaException e) {
3184: // TODO Auto-generated catch block
3185: logger.warn("OverQuotaException ", e);
3186: } catch (ServerOverloadException e) {
3187: // TODO Auto-generated catch block
3188: logger.warn("ServerOverloadException ", e);
3189: }
3190:
3191: return null;
3192: }
3193:
3194: /**
3195: * Remove the state variables used internally, on the way out.
3196: */
3197: private void cleanupState(SessionState state) {
3198: state.removeAttribute(CitationHelper.STATE_HELPER_MODE);
3199: state.removeAttribute(STATE_BACK_BUTTON_STACK);
3200: // state.removeAttribute(VelocityPortletPaneledAction.STATE_HELPER);
3201:
3202: // re-enable observers
3203: VelocityPortletPaneledAction.enableObservers(state);
3204:
3205: } // cleanupState
3206:
3207: protected String validateURL(String url)
3208: throws MalformedURLException {
3209: if (url == null || url.trim().equals("")) {
3210: throw new MalformedURLException();
3211: }
3212:
3213: url = url.trim();
3214:
3215: if (url.indexOf("://") == -1) {
3216: // if it's missing the transport, add http://
3217: url = "http://" + url;
3218: }
3219:
3220: // valid protocol?
3221: try {
3222: // test to see if the input validates as a URL.
3223: // Checks string for format only.
3224: URL u = new URL(url);
3225: } catch (MalformedURLException e1) {
3226: try {
3227: Pattern pattern = Pattern
3228: .compile("\\s*([a-zA-Z0-9]+)://([^\\n]+)");
3229: Matcher matcher = pattern.matcher(url);
3230: if (matcher.matches()) {
3231: // if URL has "unknown" protocol, check remaider with
3232: // "http" protocol and accept input it that validates.
3233: URL test = new URL("http://" + matcher.group(2));
3234: } else {
3235: throw e1;
3236: }
3237: } catch (MalformedURLException e2) {
3238: throw e1;
3239: }
3240: }
3241: return url;
3242: }
3243:
3244: public static class QuotedTextValidator {
3245:
3246: /**
3247: * Return a string for insertion in a quote in an HTML tag (as the value of an element's attribute.
3248: *
3249: * @param string
3250: * The string to escape.
3251: * @return the escaped string.
3252: */
3253: public static String escapeQuotedString(String string) {
3254: if (string == null)
3255: return "";
3256: string = string.trim();
3257: try {
3258: // convert the string to bytes in UTF-8
3259: byte[] bytes = string.getBytes("UTF-8");
3260:
3261: StringBuffer buf = new StringBuffer();
3262: for (int i = 0; i < bytes.length; i++) {
3263: byte b = bytes[i];
3264: if (b == '"') {
3265: buf.append("\\\"");
3266: } else if (b == '\\') {
3267: buf.append("\\\\");
3268: } else {
3269: buf.append((char) b);
3270: }
3271: }
3272:
3273: String rv = buf.toString();
3274: return rv;
3275: } catch (Exception e) {
3276: return string;
3277: }
3278:
3279: } // escapeQuotedString
3280: }
3281:
3282: /**
3283: * Iterate over attributes in ToolSession and remove all attributes starting with a particular prefix.
3284: * @param toolSession
3285: * @param prefix
3286: */
3287: protected void cleanup(ToolSession toolSession, String prefix) {
3288: Enumeration attributeNames = toolSession.getAttributeNames();
3289: while (attributeNames.hasMoreElements()) {
3290: String aName = (String) attributeNames.nextElement();
3291: if (aName.startsWith(prefix)) {
3292: toolSession.removeAttribute(aName);
3293: }
3294: }
3295:
3296: }
3297:
3298: public class CitationListSecurityAdviser implements SecurityAdvisor {
3299: String userId;
3300: String function;
3301: String reference;
3302:
3303: public CitationListSecurityAdviser(String userId,
3304: String function, String reference) {
3305: super ();
3306: this .userId = userId;
3307: this .function = function;
3308: this .reference = reference;
3309: }
3310:
3311: public SecurityAdvice isAllowed(String userId, String function,
3312: String reference) {
3313: SecurityAdvice advice = SecurityAdvice.PASS;
3314: if ((this .userId == null || this .userId.equals(userId))
3315: && (this .function == null || this .function
3316: .equals(function))
3317: || (this .reference == null || this .reference
3318: .equals(reference))) {
3319: advice = SecurityAdvice.ALLOWED;
3320: }
3321: return advice;
3322: }
3323:
3324: }
3325:
3326: } // class CitationHelperAction
|