Java tutorial
/********************************************************************************** * $URL$ * $Id$ *********************************************************************************** * * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009 The Sakai Foundation * * Licensed under the Educational Community License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.opensource.org/licenses/ECL-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * **********************************************************************************/ package org.sakaiproject.site.tool; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.text.NumberFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Comparator; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.ListIterator; import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.Properties; import java.util.Set; import java.util.Vector; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.io.filefilter.WildcardFileFilter; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.ObjectUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.validator.routines.EmailValidator; import org.apache.velocity.tools.generic.SortTool; import org.sakaiproject.alias.api.Alias; import org.sakaiproject.alias.api.AliasService; import org.sakaiproject.api.privacy.PrivacyManager; import org.sakaiproject.archive.api.ImportMetadata; import org.sakaiproject.archive.cover.ArchiveService; import org.sakaiproject.authz.api.AuthzGroup; import org.sakaiproject.authz.api.AuthzPermissionException; import org.sakaiproject.authz.api.GroupNotDefinedException; import org.sakaiproject.authz.api.Member; import org.sakaiproject.authz.api.PermissionsHelper; import org.sakaiproject.authz.api.Role; import org.sakaiproject.authz.api.RoleAlreadyDefinedException; import org.sakaiproject.authz.api.RoleProvider; import org.sakaiproject.authz.api.SecurityAdvisor; import org.sakaiproject.authz.api.SecurityAdvisor.SecurityAdvice; import org.sakaiproject.authz.api.AuthzGroupService; import org.sakaiproject.authz.cover.SecurityService; import org.sakaiproject.cheftool.Context; import org.sakaiproject.cheftool.JetspeedRunData; import org.sakaiproject.cheftool.PagedResourceActionII; import org.sakaiproject.cheftool.PortletConfig; import org.sakaiproject.cheftool.RunData; import org.sakaiproject.cheftool.VelocityPortlet; import org.sakaiproject.cheftool.api.Menu; import org.sakaiproject.cheftool.api.MenuItem; import org.sakaiproject.cheftool.menu.MenuEntry; import org.sakaiproject.cheftool.menu.MenuImpl; import org.sakaiproject.component.cover.ComponentManager; import org.sakaiproject.component.cover.ServerConfigurationService; import org.sakaiproject.content.api.ContentCollection; import org.sakaiproject.content.api.ContentCollectionEdit; import org.sakaiproject.content.api.ContentHostingService; import org.sakaiproject.content.api.ContentResource; import org.sakaiproject.coursemanagement.api.AcademicSession; import org.sakaiproject.coursemanagement.api.CourseOffering; import org.sakaiproject.coursemanagement.api.CourseSet; import org.sakaiproject.coursemanagement.api.Section; import org.sakaiproject.coursemanagement.api.exception.IdNotFoundException; import org.sakaiproject.entity.api.ContentExistsAware; import org.sakaiproject.entity.api.Entity; import org.sakaiproject.entity.api.EntityProducer; import org.sakaiproject.entity.api.EntityTransferrer; import org.sakaiproject.entity.api.EntityTransferrerRefMigrator; import org.sakaiproject.entity.api.HardDeleteAware; import org.sakaiproject.entity.api.Reference; import org.sakaiproject.entity.api.ResourceProperties; import org.sakaiproject.entity.api.ResourcePropertiesEdit; import org.sakaiproject.entity.cover.EntityManager; import org.sakaiproject.event.api.SessionState; import org.sakaiproject.event.api.NotificationService; import org.sakaiproject.event.cover.EventTrackingService; import org.sakaiproject.exception.IdInvalidException; import org.sakaiproject.exception.IdUnusedException; import org.sakaiproject.exception.IdUsedException; import org.sakaiproject.exception.ImportException; import org.sakaiproject.exception.InUseException; import org.sakaiproject.exception.PermissionException; import org.sakaiproject.id.cover.IdManager; import org.sakaiproject.importer.api.ImportDataSource; import org.sakaiproject.importer.api.ImportService; import org.sakaiproject.importer.api.SakaiArchive; import org.sakaiproject.importer.api.ResetOnCloseInputStream; import org.sakaiproject.javax.PagingPosition; import org.sakaiproject.lti.api.LTIService; import org.sakaiproject.site.api.Group; import org.sakaiproject.site.api.Site; import org.sakaiproject.site.api.SitePage; import org.sakaiproject.site.api.SiteService.SortType; import org.sakaiproject.site.api.ToolConfiguration; import org.sakaiproject.site.cover.SiteService; import org.sakaiproject.site.util.Participant; import org.sakaiproject.site.util.SiteComparator; import org.sakaiproject.site.util.SiteConstants; import org.sakaiproject.site.util.SiteParticipantHelper; import org.sakaiproject.site.util.SiteSetupQuestionFileParser; import org.sakaiproject.site.util.SiteTextEditUtil; import org.sakaiproject.site.util.SiteTypeUtil; import org.sakaiproject.site.util.ToolComparator; import org.sakaiproject.sitemanage.api.SectionField; import org.sakaiproject.sitemanage.api.SiteHelper; import org.sakaiproject.sitemanage.api.model.SiteSetupQuestion; import org.sakaiproject.sitemanage.api.model.SiteSetupQuestionAnswer; import org.sakaiproject.sitemanage.api.model.SiteSetupUserAnswer; import org.sakaiproject.sitemanage.api.model.SiteTypeQuestions; import org.sakaiproject.thread_local.cover.ThreadLocalManager; import org.sakaiproject.time.api.Time; import org.sakaiproject.time.api.TimeBreakdown; import org.sakaiproject.time.cover.TimeService; import org.sakaiproject.tool.api.Session; import org.sakaiproject.tool.api.Tool; import org.sakaiproject.tool.api.ToolException; import org.sakaiproject.tool.api.ToolSession; import org.sakaiproject.tool.cover.SessionManager; import org.sakaiproject.tool.cover.ToolManager; import org.sakaiproject.user.api.User; import org.sakaiproject.user.api.UserNotDefinedException; import org.sakaiproject.user.cover.UserDirectoryService; import org.sakaiproject.userauditservice.api.UserAuditRegistration; import org.sakaiproject.userauditservice.api.UserAuditService; import org.sakaiproject.shortenedurl.api.ShortenedUrlService; import org.sakaiproject.util.*; // for basiclti integration /** * <p> * SiteAction controls the interface for worksite setup. * </p> */ public class SiteAction extends PagedResourceActionII { // SAK-23491 add template_used property private static final String TEMPLATE_USED = "template_used"; /** Our log (commons). */ private static Log M_log = LogFactory.getLog(SiteAction.class); private LTIService m_ltiService = (LTIService) ComponentManager.get("org.sakaiproject.lti.api.LTIService"); private ContentHostingService m_contentHostingService = (ContentHostingService) ComponentManager .get("org.sakaiproject.content.api.ContentHostingService"); private ImportService importService = org.sakaiproject.importer.cover.ImportService.getInstance(); private static String showOrphanedMembers = ServerConfigurationService .getString("site.setup.showOrphanedMembers", "admins"); /** portlet configuration parameter values* */ /** Resource bundle using current language locale */ private static ResourceLoader rb = new ResourceLoader("sitesetupgeneric"); private static ResourceLoader cfgRb = new ResourceLoader("multipletools"); private Locale comparator_locale = rb.getLocale(); private org.sakaiproject.user.api.UserDirectoryService userDirectoryService = (org.sakaiproject.user.api.UserDirectoryService) ComponentManager .get(org.sakaiproject.user.api.UserDirectoryService.class); private org.sakaiproject.coursemanagement.api.CourseManagementService cms = (org.sakaiproject.coursemanagement.api.CourseManagementService) ComponentManager .get(org.sakaiproject.coursemanagement.api.CourseManagementService.class); private org.sakaiproject.authz.api.GroupProvider groupProvider = (org.sakaiproject.authz.api.GroupProvider) ComponentManager .get(org.sakaiproject.authz.api.GroupProvider.class); private AuthzGroupService authzGroupService = ComponentManager.get(AuthzGroupService.class); private org.sakaiproject.archive.api.ArchiveService archiveService = (org.sakaiproject.archive.api.ArchiveService) ComponentManager .get(org.sakaiproject.archive.api.ArchiveService.class); private org.sakaiproject.sitemanage.api.SectionFieldProvider sectionFieldProvider = (org.sakaiproject.sitemanage.api.SectionFieldProvider) ComponentManager .get(org.sakaiproject.sitemanage.api.SectionFieldProvider.class); private org.sakaiproject.sitemanage.api.AffiliatedSectionProvider affiliatedSectionProvider = (org.sakaiproject.sitemanage.api.AffiliatedSectionProvider) ComponentManager .get(org.sakaiproject.sitemanage.api.AffiliatedSectionProvider.class); private org.sakaiproject.sitemanage.api.SiteTypeProvider siteTypeProvider = (org.sakaiproject.sitemanage.api.SiteTypeProvider) ComponentManager .get(org.sakaiproject.sitemanage.api.SiteTypeProvider.class); private AliasService aliasService = ComponentManager.get(AliasService.class); private static org.sakaiproject.sitemanage.api.model.SiteSetupQuestionService questionService = (org.sakaiproject.sitemanage.api.model.SiteSetupQuestionService) ComponentManager .get(org.sakaiproject.sitemanage.api.model.SiteSetupQuestionService.class); private static org.sakaiproject.sitemanage.api.UserNotificationProvider userNotificationProvider = (org.sakaiproject.sitemanage.api.UserNotificationProvider) ComponentManager .get(org.sakaiproject.sitemanage.api.UserNotificationProvider.class); private static ShortenedUrlService shortenedUrlService = (ShortenedUrlService) ComponentManager .get(ShortenedUrlService.class); private static final String SITE_MODE_SITESETUP = "sitesetup"; private static final String SITE_MODE_SITEINFO = "siteinfo"; private static final String SITE_MODE_HELPER = "helper"; private static final String SITE_MODE_HELPER_DONE = "helper.done"; private static final String STATE_SITE_MODE = "site_mode"; private static final String TERM_OPTION_ALL = "-1"; protected final static String[] TEMPLATE = { "-list", // 0 "-type", "", // combined with 13 "", // chef_site-editFeatures.vm deleted. Functions are combined with chef_site-editToolGroupFeatures.vm "-editToolGroupFeatures", "", // moved to participant helper "", "", "-siteDeleteConfirm", "", "-newSiteConfirm", // 10 "", "-siteInfo-list", // 12 "-siteInfo-editInfo", "-siteInfo-editInfoConfirm", "-addRemoveFeatureConfirm", // 15 "", "", "-siteInfo-editAccess", "", "", // 20 "", "", "", "", "", // 25 "-modifyENW", "-importSites", "-siteInfo-import", "-siteInfo-duplicate", "", // 30 "", // 31 "", // 32 "", // 33 "", // 34 "", // 35 "-newSiteCourse", // 36 "-newSiteCourseManual", // 37 "", // 38 "", // 39 "", // 40 "", // 41 "-type-confirm", // 42 "-siteInfo-editClass", // 43 "-siteInfo-addCourseConfirm", // 44 "-siteInfo-importMtrlMaster", // 45 -- htripath for import // material from a file "-siteInfo-importMtrlCopy", // 46 "-siteInfo-importMtrlCopyConfirm", "-siteInfo-importMtrlCopyConfirmMsg", // 48 "", //"-siteInfo-group", // 49 moved to the group helper "", //"-siteInfo-groupedit", // 50 moved to the group helper "", //"-siteInfo-groupDeleteConfirm", // 51, moved to the group helper "", "-findCourse", // 53 "-questions", // 54 "", // 55 "", // 56 "", // 57 "-siteInfo-importSelection", //58 "-siteInfo-importMigrate", //59 "-importSitesMigrate", //60 "-siteInfo-importUser", "-uploadArchive" }; /** Name of state attribute for Site instance id */ private static final String STATE_SITE_INSTANCE_ID = "site.instance.id"; /** Name of state attribute for Site Information */ private static final String STATE_SITE_INFO = "site.info"; private static final String STATE_SITE_TYPE = "site-type"; /** Name of state attribute for possible site types */ private static final String STATE_SITE_TYPES = "site_types"; private static final String STATE_DEFAULT_SITE_TYPE = "default_site_type"; private static final String STATE_PUBLIC_CHANGEABLE_SITE_TYPES = "changeable_site_types"; private static final String STATE_PUBLIC_SITE_TYPES = "public_site_types"; private static final String STATE_PRIVATE_SITE_TYPES = "private_site_types"; private static final String STATE_DISABLE_JOINABLE_SITE_TYPE = "disable_joinable_site_types"; private final static String PROP_SITE_LANGUAGE = "locale_string"; /** * Name of the state attribute holding the site list column list is sorted * by */ private static final String SORTED_BY = "site.sorted.by"; /** Name of the state attribute holding the site list column to sort by */ private static final String SORTED_ASC = "site.sort.asc"; /** State attribute for list of sites to be deleted. */ private static final String STATE_SITE_REMOVALS = "site.removals"; /** Name of the state attribute holding the site list View selected */ private static final String STATE_VIEW_SELECTED = "site.view.selected"; private static final String STATE_TERM_VIEW_SELECTED = "site.termview.selected"; /******************* * SAK-16600 * * Refactor methods to update these values in state/context */ /** Names of lists related to tools groups */ private static final String STATE_TOOL_GROUP_LIST = "toolsByGroup"; /** Names of lists related to tools groups */ private static final String STATE_TOOL_GROUP_MULTIPLES = "toolGroupMultiples"; /** Names of lists related to tools */ private static final String STATE_TOOL_REGISTRATION_LIST = "toolRegistrationList"; private static final String STATE_TOOL_REGISTRATION_TITLE_LIST = "toolRegistrationTitleList"; private static final String STATE_TOOL_REGISTRATION_SELECTED_LIST = "toolRegistrationSelectedList"; private static final String STATE_TOOL_REGISTRATION_OLD_SELECTED_LIST = "toolRegistrationOldSelectedList"; private static final String STATE_TOOL_REGISTRATION_OLD_SELECTED_HOME = "toolRegistrationOldSelectedHome"; private static final String STATE_EXTRA_SELECTED_TOOL_LIST = "extraSelectedToolList"; private static final String STATE_TOOL_HOME_SELECTED = "toolHomeSelected"; private static final String UNGROUPED_TOOL_TITLE = "systoolgroups.ungrouped"; private static final String LTI_TOOL_TITLE = "systoolgroups.lti"; //******************** private static final String STATE_TOOL_EMAIL_ADDRESS = "toolEmailAddress"; private static final String STATE_PROJECT_TOOL_LIST = "projectToolList"; private final static String STATE_MULTIPLE_TOOL_ID_SET = "multipleToolIdSet"; private final static String STATE_MULTIPLE_TOOL_ID_TITLE_MAP = "multipleToolIdTitleMap"; private final static String STATE_MULTIPLE_TOOL_CONFIGURATION = "multipleToolConfiguration"; private final static String SITE_DEFAULT_LIST = ServerConfigurationService.getString("site.types"); private final static String DEFAULT_SITE_TYPE_SAK_PROP = ServerConfigurationService .getString("site.types.defaultType", null); private final static String[] PUBLIC_CHANGEABLE_SITE_TYPES_SAK_PROP = ServerConfigurationService .getStrings("site.types.publicChangeable"); private final static String[] PUBLIC_SITE_TYPES_SAK_PROP = ServerConfigurationService .getStrings("site.types.publicOnly"); private final static String[] PRIVATE_SITE_TYPES_SAK_PROP = ServerConfigurationService .getStrings("site.types.privateOnly"); private final static String STATE_SITE_QUEST_UNIQNAME = "site_quest_uniqname"; private static final String STATE_SITE_ADD_COURSE = "canAddCourse"; private static final String STATE_SITE_ADD_PORTFOLIO = "canAddPortfolio"; private static final String STATE_PORTFOLIO_SITE_TYPE = "portfolio"; private static final String STATE_SITE_ADD_PROJECT = "canAddProject"; private static final String STATE_PROJECT_SITE_TYPE = "project"; private static final String STATE_SITE_IMPORT_ARCHIVE = "canImportArchive"; // SAK-23468 private static final String STATE_NEW_SITE_STATUS_ISPUBLISHED = "newSiteStatusIsPublished"; private static final String STATE_NEW_SITE_STATUS_TITLE = "newSiteStatusTitle"; private static final String STATE_NEW_SITE_STATUS_ID = "newSiteStatusID"; // %%% get rid of the IdAndText tool lists and just use ToolConfiguration or // ToolRegistration lists // %%% same for CourseItems // Names for other state attributes that are lists private final static String STATE_WORKSITE_SETUP_PAGE_LIST = "wSetupPageList"; // the // list // of // site // pages // consistent // with // Worksite // Setup // page // patterns /** * The name of the state form field containing additional information for a * course request */ private static final String FORM_ADDITIONAL = "form.additional"; /** %%% in transition from putting all form variables in state */ private final static String FORM_TITLE = "form_title"; private final static String FORM_SITE_URL_BASE = "form_site_url_base"; private final static String FORM_SITE_ALIAS = "form_site_alias"; private final static String FORM_DESCRIPTION = "form_description"; private final static String FORM_HONORIFIC = "form_honorific"; private final static String FORM_INSTITUTION = "form_institution"; private final static String FORM_SUBJECT = "form_subject"; private final static String FORM_PHONE = "form_phone"; private final static String FORM_EMAIL = "form_email"; private final static String FORM_REUSE = "form_reuse"; private final static String FORM_RELATED_CLASS = "form_related_class"; private final static String FORM_RELATED_PROJECT = "form_related_project"; private final static String FORM_NAME = "form_name"; private final static String FORM_SHORT_DESCRIPTION = "form_short_description"; private final static String FORM_ICON_URL = "iconUrl"; private final static String FORM_SITEINFO_URL_BASE = "form_site_url_base"; private final static String FORM_SITEINFO_ALIASES = "form_site_aliases"; private final static String FORM_WILL_NOTIFY = "form_will_notify"; /** Context action */ private static final String CONTEXT_ACTION = "SiteAction"; /** The name of the Attribute for display template index */ private static final String STATE_TEMPLATE_INDEX = "site.templateIndex"; /** The name of the Attribute for display template index */ private static final String STATE_OVERRIDE_TEMPLATE_INDEX = "site.overrideTemplateIndex"; /** The name of the Attribute to indicate we are operating in shortcut mode */ private static final String STATE_IN_SHORTCUT = "site.currentlyInShortcut"; /** State attribute for state initialization. */ private static final String STATE_INITIALIZED = "site.initialized"; /** State attributes for using templates in site creation. */ private static final String STATE_TEMPLATE_SITE = "site.templateSite"; private static final String STATE_TEMPLATE_SITE_COPY_USERS = "site.templateSiteCopyUsers"; private static final String STATE_TEMPLATE_SITE_COPY_CONTENT = "site.templateSiteCopyContent"; private static final String STATE_TEMPLATE_PUBLISH = "site.templateSitePublish"; /** The action for menu */ private static final String STATE_ACTION = "site.action"; /** The user copyright string */ private static final String STATE_MY_COPYRIGHT = "resources.mycopyright"; /** The copyright character */ private static final String COPYRIGHT_SYMBOL = "copyright (c)"; /** The null/empty string */ private static final String NULL_STRING = ""; /** The state attribute alerting user of a sent course request */ private static final String REQUEST_SENT = "site.request.sent"; /** The state attributes in the make public vm */ private static final String STATE_JOINABLE = "state_joinable"; private static final String STATE_JOINERROLE = "state_joinerRole"; private static final String STATE_SITE_ACCESS_PUBLISH = "state_site_access_publish"; private static final String STATE_SITE_ACCESS_INCLUDE = "state_site_access_include"; /** the list of selected user */ private static final String STATE_SELECTED_USER_LIST = "state_selected_user_list"; private static final String STATE_SELECTED_PARTICIPANT_ROLES = "state_selected_participant_roles"; private static final String STATE_SELECTED_PARTICIPANTS = "state_selected_participants"; private static final String STATE_PARTICIPANT_LIST = "state_participant_list"; private static final String STATE_ADD_PARTICIPANTS = "state_add_participants"; /** for changing participant roles */ private static final String STATE_CHANGEROLE_SAMEROLE = "state_changerole_samerole"; private static final String STATE_CHANGEROLE_SAMEROLE_ROLE = "state_changerole_samerole_role"; /** for remove user */ private static final String STATE_REMOVEABLE_USER_LIST = "state_removeable_user_list"; private static final String STATE_IMPORT = "state_import"; private static final String STATE_IMPORT_SITES = "state_import_sites"; private static final String STATE_IMPORT_SITE_TOOL = "state_import_site_tool"; /** for navigating between sites in site list */ private static final String STATE_SITES = "state_sites"; private static final String STATE_PREV_SITE = "state_prev_site"; private static final String STATE_NEXT_SITE = "state_next_site"; /** for course information */ private final static String STATE_TERM_COURSE_LIST = "state_term_course_list"; private final static String STATE_TERM_COURSE_HASH = "state_term_course_hash"; private final static String STATE_TERM_SELECTED = "state_term_selected"; private final static String STATE_INSTRUCTOR_SELECTED = "state_instructor_selected"; private final static String STATE_FUTURE_TERM_SELECTED = "state_future_term_selected"; private final static String STATE_ADD_CLASS_PROVIDER = "state_add_class_provider"; private final static String STATE_ADD_CLASS_PROVIDER_CHOSEN = "state_add_class_provider_chosen"; private final static String STATE_ADD_CLASS_PROVIDER_DESCRIPTION_CHOSEN = "state_add_class_provider_description_chosen"; private final static String STATE_ADD_CLASS_MANUAL = "state_add_class_manual"; private final static String STATE_AUTO_ADD = "state_auto_add"; private final static String STATE_MANUAL_ADD_COURSE_NUMBER = "state_manual_add_course_number"; private final static String STATE_MANUAL_ADD_COURSE_FIELDS = "state_manual_add_course_fields"; public final static String PROP_SITE_REQUEST_COURSE = "site-request-course-sections"; public final static String SITE_PROVIDER_COURSE_LIST = "site_provider_course_list"; public final static String SITE_MANUAL_COURSE_LIST = "site_manual_course_list"; private final static String STATE_SUBJECT_AFFILIATES = "site.subject.affiliates"; private final static String STATE_ICONS = "icons"; public static final String SITE_DUPLICATED = "site_duplicated"; public static final String SITE_DUPLICATED_NAME = "site_duplicated_named"; // types of site whose title can not be editable public static final String TITLE_NOT_EDITABLE_SITE_TYPE = "title_not_editable_site_type"; // maximum length of a site title private static final String STATE_SITE_TITLE_MAX = "site_title_max_length"; // types of site where site view roster permission is editable public static final String EDIT_VIEW_ROSTER_SITE_TYPE = "edit_view_roster_site_type"; // htripath : for import material from file - classic import private static final String ALL_ZIP_IMPORT_SITES = "allzipImports"; private static final String FINAL_ZIP_IMPORT_SITES = "finalzipImports"; private static final String DIRECT_ZIP_IMPORT_SITES = "directzipImports"; private static final String CLASSIC_ZIP_FILE_NAME = "classicZipFileName"; private static final String SESSION_CONTEXT_ID = "sessionContextId"; // page size for worksite setup tool private static final String STATE_PAGESIZE_SITESETUP = "state_pagesize_sitesetup"; // page size for site info tool private static final String STATE_PAGESIZE_SITEINFO = "state_pagesize_siteinfo"; private static final String IMPORT_DATA_SOURCE = "import_data_source"; // Special tool id for Home page private static final String SITE_INFORMATION_TOOL = "sakai.iframe.site"; private static final String STATE_CM_LEVELS = "site.cm.levels"; private static final String STATE_CM_LEVEL_OPTS = "site.cm.level_opts"; private static final String STATE_CM_LEVEL_SELECTIONS = "site.cm.level.selections"; private static final String STATE_CM_SELECTED_SECTION = "site.cm.selectedSection"; private static final String STATE_CM_REQUESTED_SECTIONS = "site.cm.requested"; private static final String STATE_CM_SELECTED_SECTIONS = "site.cm.selectedSections"; private static final String STATE_PROVIDER_SECTION_LIST = "site_provider_section_list"; private static final String STATE_CM_CURRENT_USERID = "site_cm_current_userId"; private static final String STATE_CM_AUTHORIZER_LIST = "site_cm_authorizer_list"; private static final String STATE_CM_AUTHORIZER_SECTIONS = "site_cm_authorizer_sections"; private String cmSubjectCategory; private boolean warnedNoSubjectCategory = false; // the string marks the protocol part in url private static final String PROTOCOL_STRING = "://"; /** * {@link org.sakaiproject.component.api.ServerConfigurationService} property. * If <code>false</code>, ensures that a site's joinability settings are not affected should * that site be <em>edited</em> after its type has been enumerated by a * "wsetup.disable.joinable" property. Code should cause this prop value to * default to <code>true</code> to preserve backward compatibility. Property * naming tries to match mini-convention established by "wsetup.disable.joinable" * (which has no corresponding constant). * * <p>Has no effect on the site creation process -- only site editing</p> * * @see #doUpdate_site_access_joinable(RunData, SessionState, ParameterParser, Site) */ public static final String CONVERT_NULL_JOINABLE_TO_UNJOINABLE = "wsetup.convert.null.joinable.to.unjoinable"; private static final String SITE_TEMPLATE_PREFIX = "template"; private static final String STATE_TYPE_SELECTED = "state_type_selected"; // the template index after exist the question mode private static final String STATE_SITE_SETUP_QUESTION_NEXT_TEMPLATE = "state_site_setup_question_next_template"; // SAK-12912, the answers to site setup questions private static final String STATE_SITE_SETUP_QUESTION_ANSWER = "state_site_setup_question_answer"; // SAK-13389, the non-official participant private static final String ADD_NON_OFFICIAL_PARTICIPANT = "add_non_official_participant"; // the list of visited templates private static final String STATE_VISITED_TEMPLATES = "state_visited_templates"; private String STATE_GROUP_HELPER_ID = "state_group_helper_id"; // used in the configuration file to specify which tool attributes are configurable through WSetup tool, and what are the default value for them. private String CONFIG_TOOL_ATTRIBUTE = "wsetup.config.tool.attribute_"; private String CONFIG_TOOL_ATTRIBUTE_DEFAULT = "wsetup.config.tool.attribute.default_"; // used in the configuration file to specify the default tool title private String CONFIG_TOOL_TITLE = "wsetup.config.tool.title_"; // home tool id private static final String TOOL_ID_HOME = "home"; // Site Info tool id private static final String TOOL_ID_SITEINFO = "sakai.siteinfo"; // synoptic tool ids private static final String TOOL_ID_SUMMARY_CALENDAR = "sakai.summary.calendar"; private static final String TOOL_ID_SYNOPTIC_ANNOUNCEMENT = "sakai.synoptic.announcement"; private static final String TOOL_ID_SYNOPTIC_CHAT = "sakai.synoptic.chat"; private static final String TOOL_ID_SYNOPTIC_MESSAGECENTER = "sakai.synoptic.messagecenter"; private static final String TOOL_ID_SYNOPTIC_DISCUSSION = "sakai.synoptic.discussion"; private static final String IMPORT_QUEUED = "import.queued"; // map of synoptic tool and the related tool ids private final static Map<String, List<String>> SYNOPTIC_TOOL_ID_MAP; static { SYNOPTIC_TOOL_ID_MAP = new HashMap<String, List<String>>(); SYNOPTIC_TOOL_ID_MAP.put(TOOL_ID_SUMMARY_CALENDAR, new ArrayList(Arrays.asList("sakai.schedule"))); SYNOPTIC_TOOL_ID_MAP.put(TOOL_ID_SYNOPTIC_ANNOUNCEMENT, new ArrayList(Arrays.asList("sakai.announcements"))); SYNOPTIC_TOOL_ID_MAP.put(TOOL_ID_SYNOPTIC_CHAT, new ArrayList(Arrays.asList("sakai.chat"))); SYNOPTIC_TOOL_ID_MAP.put(TOOL_ID_SYNOPTIC_MESSAGECENTER, new ArrayList(Arrays.asList("sakai.messages", "sakai.forums", "sakai.messagecenter"))); SYNOPTIC_TOOL_ID_MAP.put(TOOL_ID_SYNOPTIC_DISCUSSION, new ArrayList(Arrays.asList("sakai.discussion"))); } // map of synoptic tool and message bundle properties, used to lookup an internationalized tool title private final static Map<String, String> SYNOPTIC_TOOL_TITLE_MAP; static { SYNOPTIC_TOOL_TITLE_MAP = new HashMap<String, String>(); SYNOPTIC_TOOL_TITLE_MAP.put(TOOL_ID_SUMMARY_CALENDAR, "java.reccal"); SYNOPTIC_TOOL_TITLE_MAP.put(TOOL_ID_SYNOPTIC_ANNOUNCEMENT, "java.recann"); SYNOPTIC_TOOL_TITLE_MAP.put(TOOL_ID_SYNOPTIC_CHAT, "java.recent"); SYNOPTIC_TOOL_TITLE_MAP.put(TOOL_ID_SYNOPTIC_MESSAGECENTER, "java.recmsg"); SYNOPTIC_TOOL_TITLE_MAP.put(TOOL_ID_SYNOPTIC_DISCUSSION, "java.recdisc"); } /** the web content tool id **/ private final static String WEB_CONTENT_TOOL_ID = "sakai.iframe"; private final static String SITE_INFO_TOOL_ID = "sakai.iframe.site"; private final static String WEB_CONTENT_TOOL_SOURCE_CONFIG = "source"; private final static String WEB_CONTENT_TOOL_SOURCE_CONFIG_VALUE = "http://"; /** the news tool **/ private final static String NEWS_TOOL_ID = "sakai.news"; private final static String NEWS_TOOL_CHANNEL_CONFIG = "channel-url"; private final static String NEWS_TOOL_CHANNEL_CONFIG_VALUE = "http://sakaiproject.org/feed"; private final static String LESSONS_TOOL_ID = "sakai.lessonbuildertool"; private final static int UUID_LENGTH = 36; /** the course set definition from CourseManagementService **/ private final static String STATE_COURSE_SET = "state_course_set"; // the maximum tool title length enforced in UI private final static int MAX_TOOL_TITLE_LENGTH = 20; private final static String SORT_KEY_SESSION = "worksitesetup.sort.key.session"; private final static String SORT_ORDER_SESSION = "worksitesetup.sort.order.session"; private final static String SORT_KEY_COURSE_SET = "worksitesetup.sort.key.courseSet"; private final static String SORT_ORDER_COURSE_SET = "worksitesetup.sort.order.courseSet"; private final static String SORT_KEY_COURSE_OFFERING = "worksitesetup.sort.key.courseOffering"; private final static String SORT_ORDER_COURSE_OFFERING = "worksitesetup.sort.order.courseOffering"; private final static String SORT_KEY_SECTION = "worksitesetup.sort.key.section"; private final static String SORT_ORDER_SECTION = "worksitesetup.sort.order.section"; // bjones86 - SAK-23255 private final static String CONTEXT_IS_ADMIN = "isAdmin"; private final static String CONTEXT_SKIP_MANUAL_COURSE_CREATION = "skipManualCourseCreation"; private final static String CONTEXT_SKIP_COURSE_SECTION_SELECTION = "skipCourseSectionSelection"; private final static String CONTEXT_FILTER_TERMS = "filterTerms"; private final static String SAK_PROP_SKIP_MANUAL_COURSE_CREATION = "wsetup.skipManualCourseCreation"; private final static String SAK_PROP_SKIP_COURSE_SECTION_SELECTION = "wsetup.skipCourseSectionSelection"; //SAK-22432 Template descriptions are not copied private final static String SAK_PROP_COPY_TEMPLATE_DESCRIPTION = "site.setup.copy.template.description"; //Setup property to require (or not require) authorizer private static final String SAK_PROP_REQUIRE_AUTHORIZER = "wsetup.requireAuthorizer"; //Setup property to email authorizer (default to true) private static final String SAK_PROP_EMAIL_AUTHORIZER = "wsetup.emailAuthorizer"; private List prefLocales = new ArrayList(); private static final String VM_ALLOWED_ROLES_DROP_DOWN = "allowedRoles"; // bjones86 - SAK-23256 private static final String SAK_PROP_FILTER_TERMS = "worksitesetup.filtertermdropdowns"; private static final String CONTEXT_HAS_TERMS = "hasTerms"; private static final String SAK_PROP_AUTO_FILTER_TERM = "site.setup.autoFilterTerm"; private static final String SAK_PROP_IMPORT_NOTIFICATION = "site.setup.import.notification"; // state variable for whether any multiple instance tool has been selected private String STATE_MULTIPLE_TOOL_INSTANCE_SELECTED = "state_multiple_tool_instance_selected"; // state variable for lti tools private String STATE_LTITOOL_LIST = "state_ltitool_list"; // state variable for selected lti tools in site private String STATE_LTITOOL_EXISTING_SELECTED_LIST = "state_ltitool_existing_selected_list"; // state variable for selected lti tools during tool modification private String STATE_LTITOOL_SELECTED_LIST = "state_ltitool_selected_list"; // special prefix String for basiclti tool ids private String LTITOOL_ID_PREFIX = "lti_"; private String m_filePath; private String moreInfoPath; private String libraryPath; private static final String STATE_HARD_DELETE = "hardDelete"; private static final String STATE_CREATE_FROM_ARCHIVE = "createFromArchive"; private static final String STATE_UPLOADED_ARCHIVE_PATH = "uploadedArchivePath"; private static final String STATE_UPLOADED_ARCHIVE_NAME = "uploadedArchiveNAme"; private static UserAuditRegistration userAuditRegistration = (UserAuditRegistration) ComponentManager .get("org.sakaiproject.userauditservice.api.UserAuditRegistration.sitemanage"); private static UserAuditService userAuditService = (UserAuditService) ComponentManager .get(UserAuditService.class); private PrivacyManager privacyManager = (PrivacyManager) ComponentManager.get(PrivacyManager.class); // SAK-28990 - enable/disable continue with no roster private static final String VM_CONT_NO_ROSTER_ENABLED = "contNoRosterEnabled"; private static final String SAK_PROP_CONT_NO_ROSTER_ENABLED = "sitemanage.continueWithNoRoster"; private static final String VM_ADD_ROSTER_AUTH_REQUIRED = "authorizationRequired"; /** * what are the tool ids within Home page? * If this is for a newly added Home tool, get the tool ids from template site or system set default * Else if this is an existing Home tool, get the tool ids from the page * @param state * @param newHomeTool * @param homePage * @return */ private List<String> getHomeToolIds(SessionState state, boolean newHomeTool, SitePage homePage) { List<String> rv = new Vector<String>(); // if this is a new Home tool page to be added, get the tool ids from definition (template site first, and then configurations) Site site = getStateSite(state); String siteType = site != null ? site.getType() : ""; // First: get the tool ids from configuration files // initially by "wsetup.home.toolids" + site type, and if missing, use "wsetup.home.toolids" if (ServerConfigurationService.getStrings("wsetup.home.toolids." + siteType) != null) { rv = new ArrayList( Arrays.asList(ServerConfigurationService.getStrings("wsetup.home.toolids." + siteType))); } else if (ServerConfigurationService.getStrings("wsetup.home.toolids") != null) { rv = new ArrayList(Arrays.asList(ServerConfigurationService.getStrings("wsetup.home.toolids"))); } // Second: if tool list is empty, get it from the template site settings if (rv.isEmpty()) { // template site Site templateSite = null; String templateSiteId = ""; if (SiteService.isUserSite(site.getId())) { // myworkspace type site: get user type first, and then get the template site try { User user = UserDirectoryService.getUser(SiteService.getSiteUserId(site.getId())); templateSiteId = SiteService.USER_SITE_TEMPLATE + "." + user.getType(); templateSite = SiteService.getSite(templateSiteId); } catch (Throwable t) { M_log.debug(this + ": getHomeToolIds cannot find site " + templateSiteId + t.getMessage()); // use the fall-back, user template site try { templateSiteId = SiteService.USER_SITE_TEMPLATE; templateSite = SiteService.getSite(templateSiteId); } catch (Throwable tt) { M_log.debug(this + ": getHomeToolIds cannot find site " + templateSiteId + tt.getMessage()); } } } else { // not myworkspace site // first: see whether it is during site creation process and using a template site templateSite = (Site) state.getAttribute(STATE_TEMPLATE_SITE); if (templateSite == null) { // second: if no template is chosen by user, then use template based on site type templateSiteId = SiteService.SITE_TEMPLATE + "." + siteType; try { templateSite = SiteService.getSite(templateSiteId); } catch (Throwable t) { M_log.debug(this + ": getHomeToolIds cannot find site " + templateSiteId + t.getMessage()); // thrid: if cannot find template site with the site type, use the default template templateSiteId = SiteService.SITE_TEMPLATE; try { templateSite = SiteService.getSite(templateSiteId); } catch (Throwable tt) { M_log.debug( this + ": getHomeToolIds cannot find site " + templateSiteId + tt.getMessage()); } } } } if (templateSite != null) { // get Home page and embedded tool ids for (SitePage page : (List<SitePage>) templateSite.getPages()) { String title = page.getTitle(); if (isHomePage(page)) { // found home page, add all tool ids to return value for (ToolConfiguration tConfiguration : (List<ToolConfiguration>) page.getTools()) { String toolId = tConfiguration.getToolId(); if (ToolManager.getTool(toolId) != null) rv.add(toolId); } break; } } } } // Third: if the tool id list is still empty because we cannot find any template site yet, use the default settings if (rv.isEmpty()) { if (siteType.equalsIgnoreCase("myworkspace")) { // first try with MOTD tool if (ToolManager.getTool("sakai.motd") != null) rv.add("sakai.motd"); if (rv.isEmpty()) { // then try with the myworkspace information tool if (ToolManager.getTool("sakai.iframe.myworkspace") != null) rv.add("sakai.iframe.myworkspace"); } } else { // try the site information tool if (ToolManager.getTool("sakai.iframe.site") != null) rv.add("sakai.iframe.site"); } // synoptical tools if (ToolManager.getTool(TOOL_ID_SUMMARY_CALENDAR) != null) { rv.add(TOOL_ID_SUMMARY_CALENDAR); } if (ToolManager.getTool(TOOL_ID_SYNOPTIC_ANNOUNCEMENT) != null) { rv.add(TOOL_ID_SYNOPTIC_ANNOUNCEMENT); } if (ToolManager.getTool(TOOL_ID_SYNOPTIC_CHAT) != null) { rv.add(TOOL_ID_SYNOPTIC_CHAT); } if (ToolManager.getTool(TOOL_ID_SYNOPTIC_MESSAGECENTER) != null) { rv.add(TOOL_ID_SYNOPTIC_MESSAGECENTER); } } // Fourth: if this is an existing Home tool page, get any extra tool ids in the page already back to the list if (!newHomeTool) { // found home page, add all tool ids to return value for (ToolConfiguration tConfiguration : (List<ToolConfiguration>) homePage.getTools()) { String hToolId = tConfiguration.getToolId(); if (!rv.contains(hToolId)) { rv.add(hToolId); } } } return rv; } /* * Configure directory for moreInfo content */ private String setMoreInfoPath(ServletContext ctx) { String rpath = ctx.getRealPath(""); String ctxPath = ctx.getServletContextName(); String rserve = StringUtils.remove(rpath, ctxPath); return rserve; } /** * Populate the state object, if needed. */ protected void initState(SessionState state, VelocityPortlet portlet, JetspeedRunData rundata) { ServletContext ctx = rundata.getRequest().getSession().getServletContext(); String serverContextPath = ServerConfigurationService.getString("config.sitemanage.moreInfoDir", "library/image/"); libraryPath = File.separator + serverContextPath; moreInfoPath = setMoreInfoPath(ctx) + serverContextPath; // Cleanout if the helper has been asked to start afresh. if (state.getAttribute(SiteHelper.SITE_CREATE_START) != null) { cleanState(state); cleanStateHelper(state); // Removed from possible previous invokations. state.removeAttribute(SiteHelper.SITE_CREATE_START); state.removeAttribute(SiteHelper.SITE_CREATE_CANCELLED); state.removeAttribute(SiteHelper.SITE_CREATE_SITE_ID); } super.initState(state, portlet, rundata); // store current userId in state User user = UserDirectoryService.getCurrentUser(); String userId = user.getEid(); state.setAttribute(STATE_CM_CURRENT_USERID, userId); PortletConfig config = portlet.getPortletConfig(); // types of sites that can either be public or private addSiteTypesToStateFromPropertyOrToolReg(state, STATE_PUBLIC_CHANGEABLE_SITE_TYPES, PUBLIC_CHANGEABLE_SITE_TYPES_SAK_PROP, "publicChangeableSiteTypes", config); // type of sites that are always public addSiteTypesToStateFromPropertyOrToolReg(state, STATE_PUBLIC_SITE_TYPES, PUBLIC_SITE_TYPES_SAK_PROP, "publicSiteTypes", config); // types of sites that are always private addSiteTypesToStateFromPropertyOrToolReg(state, STATE_PRIVATE_SITE_TYPES, PRIVATE_SITE_TYPES_SAK_PROP, "privateSiteTypes", config); // default site type if (state.getAttribute(STATE_DEFAULT_SITE_TYPE) == null) { String defaultType = DEFAULT_SITE_TYPE_SAK_PROP; if (defaultType == null) // not set via sakai properties, fall back to tool registration { defaultType = StringUtils.trimToEmpty(config.getInitParameter("defaultSiteType")); } state.setAttribute(STATE_DEFAULT_SITE_TYPE, defaultType); } // certain type(s) of site cannot get its "joinable" option set if (state.getAttribute(STATE_DISABLE_JOINABLE_SITE_TYPE) == null) { if (ServerConfigurationService.getStrings("wsetup.disable.joinable") != null) { state.setAttribute(STATE_DISABLE_JOINABLE_SITE_TYPE, new ArrayList( Arrays.asList(ServerConfigurationService.getStrings("wsetup.disable.joinable")))); } else { state.setAttribute(STATE_DISABLE_JOINABLE_SITE_TYPE, new Vector()); } } if (state.getAttribute(STATE_TOP_PAGE_MESSAGE) == null) { state.setAttribute(STATE_TOP_PAGE_MESSAGE, Integer.valueOf(0)); } // skins if any if (state.getAttribute(STATE_ICONS) == null) { setupIcons(state); } if (ServerConfigurationService.getStrings("site.type.titleNotEditable") != null) { state.setAttribute(TITLE_NOT_EDITABLE_SITE_TYPE, new ArrayList( Arrays.asList(ServerConfigurationService.getStrings("site.type.titleNotEditable")))); } else { state.setAttribute(TITLE_NOT_EDITABLE_SITE_TYPE, new ArrayList(Arrays .asList(new String[] { ServerConfigurationService.getString("courseSiteType", "course") }))); } if (state.getAttribute(EDIT_VIEW_ROSTER_SITE_TYPE) == null) { List siteTypes = new Vector(); if (ServerConfigurationService.getStrings("editViewRosterSiteType") != null) { siteTypes = new ArrayList( Arrays.asList(ServerConfigurationService.getStrings("editViewRosterSiteType"))); } state.setAttribute(EDIT_VIEW_ROSTER_SITE_TYPE, siteTypes); } if (state.getAttribute(STATE_SITE_MODE) == null) { // get site tool mode from tool registry String site_mode = config.getInitParameter(STATE_SITE_MODE); // When in helper mode we don't have if (site_mode == null) { site_mode = SITE_MODE_HELPER; } state.setAttribute(STATE_SITE_MODE, site_mode); } } // initState /** * If not yet set, adds the given site type list to the state, either from sakai.properties if available, or from the tool registration configuration * * @param state the session state * @param stateKey state attribute the site type list should be added as * @param typesFromProperty site type list from sakai.properties, may be null if property not set * @param toolRegKey the key for the site type list property in the tool registration * @param config the tool registration configuration */ private void addSiteTypesToStateFromPropertyOrToolReg(SessionState state, String stateKey, String[] typesFromProperty, String toolRegKey, PortletConfig config) { if (state.getAttribute(stateKey) == null) { List<String> siteTypes = new ArrayList<>(); if (typesFromProperty != null) // override tool registration with sakai properties { siteTypes.addAll(Arrays.asList(typesFromProperty)); } else // sakai property not set, fall back to tool registration { String toolRegTypes = StringUtils.trimToEmpty(config.getInitParameter(toolRegKey)); siteTypes.addAll(Arrays.asList(toolRegTypes.split(","))); } state.setAttribute(stateKey, siteTypes); } } /** * cleanState removes the current site instance and it's properties from * state */ private void cleanState(SessionState state) { state.removeAttribute(STATE_SITE_INSTANCE_ID); state.removeAttribute(STATE_SITE_INFO); state.removeAttribute(STATE_SITE_TYPE); state.removeAttribute(STATE_TOOL_REGISTRATION_SELECTED_LIST); state.removeAttribute(STATE_TOOL_REGISTRATION_OLD_SELECTED_LIST); state.removeAttribute(STATE_TOOL_REGISTRATION_OLD_SELECTED_HOME); state.removeAttribute(STATE_TOOL_EMAIL_ADDRESS); state.removeAttribute(STATE_TOOL_HOME_SELECTED); state.removeAttribute(STATE_SELECTED_USER_LIST); state.removeAttribute(STATE_JOINABLE); state.removeAttribute(STATE_JOINERROLE); state.removeAttribute(STATE_SITE_QUEST_UNIQNAME); state.removeAttribute(STATE_IMPORT); state.removeAttribute(STATE_IMPORT_SITES); state.removeAttribute(STATE_IMPORT_SITE_TOOL); // remove the state attributes related to multi-tool selection state.removeAttribute(STATE_WORKSITE_SETUP_PAGE_LIST); state.removeAttribute(STATE_MULTIPLE_TOOL_ID_SET); state.removeAttribute(STATE_MULTIPLE_TOOL_ID_TITLE_MAP); state.removeAttribute(STATE_MULTIPLE_TOOL_CONFIGURATION); state.removeAttribute(STATE_TOOL_REGISTRATION_LIST); state.removeAttribute(STATE_TOOL_REGISTRATION_TITLE_LIST); // remove those state attributes related to course site creation state.removeAttribute(STATE_TERM_COURSE_LIST); state.removeAttribute(STATE_TERM_COURSE_HASH); state.removeAttribute(STATE_TERM_SELECTED); state.removeAttribute(STATE_INSTRUCTOR_SELECTED); state.removeAttribute(STATE_FUTURE_TERM_SELECTED); state.removeAttribute(STATE_ADD_CLASS_PROVIDER); state.removeAttribute(STATE_ADD_CLASS_PROVIDER_CHOSEN); state.removeAttribute(STATE_ADD_CLASS_PROVIDER_DESCRIPTION_CHOSEN); state.removeAttribute(STATE_ADD_CLASS_MANUAL); state.removeAttribute(STATE_AUTO_ADD); state.removeAttribute(STATE_MANUAL_ADD_COURSE_NUMBER); state.removeAttribute(STATE_MANUAL_ADD_COURSE_FIELDS); state.removeAttribute(STATE_PROVIDER_SECTION_LIST); state.removeAttribute(STATE_CM_LEVELS); state.removeAttribute(STATE_CM_LEVEL_SELECTIONS); state.removeAttribute(STATE_CM_SELECTED_SECTION); state.removeAttribute(STATE_CM_REQUESTED_SECTIONS); state.removeAttribute(STATE_CM_CURRENT_USERID); state.removeAttribute(STATE_CM_AUTHORIZER_LIST); state.removeAttribute(STATE_CM_AUTHORIZER_SECTIONS); state.removeAttribute(FORM_ADDITIONAL); // don't we need to clean this // too? -daisyf state.removeAttribute(STATE_TEMPLATE_SITE); state.removeAttribute(STATE_TYPE_SELECTED); state.removeAttribute(STATE_SITE_SETUP_QUESTION_ANSWER); state.removeAttribute(STATE_SITE_SETUP_QUESTION_NEXT_TEMPLATE); // lti tools state.removeAttribute(STATE_LTITOOL_EXISTING_SELECTED_LIST); state.removeAttribute(STATE_LTITOOL_SELECTED_LIST); // bjones86 - SAK-24423 - remove joinable site settings from the state JoinableSiteSettings.removeJoinableSiteSettingsFromState(state); } // cleanState /** * Fire up the permissions editor */ public void doPermissions(RunData data, Context context) { // get into helper mode with this helper tool startHelper(data.getRequest(), "sakai.permissions.helper"); SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); String contextString = ToolManager.getCurrentPlacement().getContext(); String siteRef = SiteService.siteReference(contextString); // if it is in Worksite setup tool, pass the selected site's reference if (state.getAttribute(STATE_SITE_MODE) != null && ((String) state.getAttribute(STATE_SITE_MODE)).equals(SITE_MODE_SITESETUP)) { if (state.getAttribute(STATE_SITE_INSTANCE_ID) != null) { Site s = getStateSite(state); if (s != null) { siteRef = s.getReference(); } } } // setup for editing the permissions of the site for this tool, using // the roles of this site, too state.setAttribute(PermissionsHelper.TARGET_REF, siteRef); // ... with this description state.setAttribute(PermissionsHelper.DESCRIPTION, rb.getString("setperfor") + " " + SiteService.getSiteDisplay(contextString)); // ... showing only locks that are prpefixed with this state.setAttribute(PermissionsHelper.PREFIX, "site."); } // doPermissions /** * Build the context for shortcut display */ public String buildShortcutPanelContext(VelocityPortlet portlet, Context context, RunData data, SessionState state) { return buildMainPanelContext(portlet, context, data, state, true); } /** * Build the context for normal display */ public String buildMainPanelContext(VelocityPortlet portlet, Context context, RunData data, SessionState state) { return buildMainPanelContext(portlet, context, data, state, false); } /** * Build the context for normal/shortcut display and detect switches */ public String buildMainPanelContext(VelocityPortlet portlet, Context context, RunData data, SessionState state, boolean inShortcut) { rb = new ResourceLoader("sitesetupgeneric"); context.put("tlang", rb); context.put("clang", cfgRb); // TODO: what is all this doing? if we are in helper mode, we are // already setup and don't get called here now -ggolden /* * String helperMode = (String) * state.getAttribute(PermissionsAction.STATE_MODE); if (helperMode != * null) { Site site = getStateSite(state); if (site != null) { if * (site.getType() != null && ((List) * state.getAttribute(EDIT_VIEW_ROSTER_SITE_TYPE)).contains(site.getType())) { * context.put("editViewRoster", Boolean.TRUE); } else { * context.put("editViewRoster", Boolean.FALSE); } } else { * context.put("editViewRoster", Boolean.FALSE); } // for new, don't * show site.del in Permission page context.put("hiddenLock", * "site.del"); * * String template = PermissionsAction.buildHelperContext(portlet, * context, data, state); if (template == null) { addAlert(state, * rb.getString("theisa")); } else { return template; } } */ String template = null; context.put("action", CONTEXT_ACTION); // updatePortlet(state, portlet, data); if (state.getAttribute(STATE_INITIALIZED) == null) { init(portlet, data, state); String overRideTemplate = (String) state.getAttribute(STATE_OVERRIDE_TEMPLATE_INDEX); if (overRideTemplate != null) { state.removeAttribute(STATE_OVERRIDE_TEMPLATE_INDEX); state.setAttribute(STATE_TEMPLATE_INDEX, overRideTemplate); } } // Track when we come into Main panel most recently from Shortcut Panel // Reset the state and template if we *just* came into Main from Shortcut if (inShortcut) { state.setAttribute(STATE_IN_SHORTCUT, "true"); } else { String fromShortcut = (String) state.getAttribute(STATE_IN_SHORTCUT); if ("true".equals(fromShortcut)) { cleanState(state); state.setAttribute(STATE_TEMPLATE_INDEX, "0"); } state.removeAttribute(STATE_IN_SHORTCUT); } String indexString = (String) state.getAttribute(STATE_TEMPLATE_INDEX); // update the visited template list with the current template index addIntoStateVisitedTemplates(state, indexString); template = buildContextForTemplate(getPrevVisitedTemplate(state), Integer.valueOf(indexString), portlet, context, data, state); return template; } // buildMainPanelContext /** * add index into the visited template indices list * @param state * @param index */ private void addIntoStateVisitedTemplates(SessionState state, String index) { List<String> templateIndices = (List<String>) state.getAttribute(STATE_VISITED_TEMPLATES); if (templateIndices == null) { templateIndices = new Vector<String>(); } if (templateIndices.size() == 0 || !templateIndices.contains(index)) { // this is to prevent from page refreshing accidentally updates the list templateIndices.add(index); state.setAttribute(STATE_VISITED_TEMPLATES, templateIndices); } } /** * remove the last index * @param state */ private void removeLastIndexInStateVisitedTemplates(SessionState state) { List<String> templateIndices = (List<String>) state.getAttribute(STATE_VISITED_TEMPLATES); if (templateIndices != null && templateIndices.size() > 0) { // this is to prevent from page refreshing accidentally updates the list templateIndices.remove(templateIndices.size() - 1); state.setAttribute(STATE_VISITED_TEMPLATES, templateIndices); } } private String getPrevVisitedTemplate(SessionState state) { List<String> templateIndices = (List<String>) state.getAttribute(STATE_VISITED_TEMPLATES); if (templateIndices != null && templateIndices.size() > 1) { return templateIndices.get(templateIndices.size() - 2); } else { return null; } } /** * whether template indexed has been visited * @param state * @param templateIndex * @return */ private boolean isTemplateVisited(SessionState state, String templateIndex) { boolean rv = false; List<String> templateIndices = (List<String>) state.getAttribute(STATE_VISITED_TEMPLATES); if (templateIndices != null && templateIndices.size() > 0) { rv = templateIndices.contains(templateIndex); } return rv; } /** * Build the context for each template using template_index parameter passed * in a form hidden field. Each case is associated with a template. (Not all * templates implemented). See String[] TEMPLATES. * * @param index * is the number contained in the template's template_index */ private String buildContextForTemplate(String preIndex, int index, VelocityPortlet portlet, Context context, RunData data, SessionState state) { String realmId = ""; String site_type = ""; String sortedBy = ""; String sortedAsc = ""; ParameterParser params = data.getParameters(); context.put("tlang", rb); String alert = (String) state.getAttribute(STATE_MESSAGE); context.put("alertMessage", state.getAttribute(STATE_MESSAGE)); context.put("siteTextEdit", new SiteTextEditUtil()); //SAK-29525 Open Template list by default when creating site context.put("isExpandTemplates", ServerConfigurationService.getBoolean("site.setup.creation.expand.template", false)); // the last visited template index if (preIndex != null) context.put("backIndex", preIndex); // SAK-16600 adjust index for toolGroup mode if (index == 3) index = 4; context.put("templateIndex", String.valueOf(index)); // If cleanState() has removed SiteInfo, get a new instance into state SiteInfo siteInfo = new SiteInfo(); if (state.getAttribute(STATE_SITE_INFO) != null) { siteInfo = (SiteInfo) state.getAttribute(STATE_SITE_INFO); } else { state.setAttribute(STATE_SITE_INFO, siteInfo); } // Lists used in more than one template // Access List roles = new Vector(); // the hashtables for News and Web Content tools Hashtable newsTitles = new Hashtable(); Hashtable newsUrls = new Hashtable(); Hashtable wcTitles = new Hashtable(); Hashtable wcUrls = new Hashtable(); List toolRegistrationList = new Vector(); List toolRegistrationSelectedList = new Vector(); ResourceProperties siteProperties = null; // all site types context.put("courseSiteTypeStrings", SiteService.getSiteTypeStrings("course")); context.put("portfolioSiteTypeStrings", SiteService.getSiteTypeStrings("portfolio")); context.put("projectSiteTypeStrings", SiteService.getSiteTypeStrings("project")); //can the user create course sites? context.put(STATE_SITE_ADD_COURSE, SiteService.allowAddCourseSite()); // can the user create portfolio sites? context.put("portfolioSiteType", STATE_PORTFOLIO_SITE_TYPE); context.put(STATE_SITE_ADD_PORTFOLIO, SiteService.allowAddPortfolioSite()); // can the user create project sites? context.put("projectSiteType", STATE_PROJECT_SITE_TYPE); context.put(STATE_SITE_ADD_PROJECT, SiteService.allowAddProjectSite()); // can the user user create sites from archives? context.put(STATE_SITE_IMPORT_ARCHIVE, SiteService.allowImportArchiveSite()); Site site = getStateSite(state); List unJoinableSiteTypes = (List) state.getAttribute(STATE_DISABLE_JOINABLE_SITE_TYPE); switch (index) { case 0: /* * buildContextForTemplate chef_site-list.vm * */ // site types List sTypes = (List) state.getAttribute(STATE_SITE_TYPES); // make sure auto-updates are enabled Hashtable views = new Hashtable(); // Allow a user to see their deleted sites. if (ServerConfigurationService.getBoolean("site.soft.deletion", false)) { views.put(SiteConstants.SITE_TYPE_DELETED, rb.getString("java.sites.deleted")); if (SiteConstants.SITE_TYPE_DELETED.equals((String) state.getAttribute(STATE_VIEW_SELECTED))) { context.put("canSeeSoftlyDeletedSites", true); } } // top menu bar Menu bar = new MenuImpl(portlet, data, (String) state.getAttribute(STATE_ACTION)); context.put("menu", bar); if (SiteService.allowAddSite(null)) { bar.add(new MenuEntry(rb.getString("java.new"), "doNew_site")); } bar.add(new MenuEntry(rb.getString("java.revise"), null, true, MenuItem.CHECKED_NA, "doGet_site", "sitesForm")); bar.add(new MenuEntry(rb.getString("java.delete"), null, true, MenuItem.CHECKED_NA, "doMenu_site_delete", "sitesForm")); // If we're in the restore view context.put("showRestore", SiteConstants.SITE_TYPE_DELETED.equals((String) state.getAttribute(STATE_VIEW_SELECTED))); if (SecurityService.isSuperUser()) { context.put("superUser", Boolean.TRUE); } else { context.put("superUser", Boolean.FALSE); } views.put(SiteConstants.SITE_TYPE_ALL, rb.getString("java.allmy")); views.put(SiteConstants.SITE_TYPE_MYWORKSPACE, rb.getFormattedMessage("java.sites", new Object[] { rb.getString("java.my") })); for (int sTypeIndex = 0; sTypeIndex < sTypes.size(); sTypeIndex++) { String type = (String) sTypes.get(sTypeIndex); views.put(type, rb.getFormattedMessage("java.sites", new Object[] { type })); } List<String> moreTypes = siteTypeProvider.getTypesForSiteList(); if (!moreTypes.isEmpty()) { for (String mType : moreTypes) { views.put(mType, rb.getFormattedMessage("java.sites", new Object[] { mType })); } } // Allow SuperUser to see all deleted sites. if (ServerConfigurationService.getBoolean("site.soft.deletion", false)) { views.put(SiteConstants.SITE_TYPE_DELETED, rb.getString("java.sites.deleted")); } // default view if (state.getAttribute(STATE_VIEW_SELECTED) == null) { state.setAttribute(STATE_VIEW_SELECTED, SiteConstants.SITE_TYPE_ALL); } if (ServerConfigurationService.getBoolean("sitesetup.show.unpublished", false) && !SecurityService.isSuperUser()) { views.put(SiteConstants.SITE_ACTIVE, rb.getString("java.myActive")); views.put(SiteConstants.SITE_INACTIVE, rb.getString("java.myInactive")); } // sort the keys in the views lookup List<String> viewKeys = Collections.list(views.keys()); Collections.sort(viewKeys); context.put("viewKeys", viewKeys); context.put("views", views); if (state.getAttribute(STATE_VIEW_SELECTED) != null) { context.put("viewSelected", (String) state.getAttribute(STATE_VIEW_SELECTED)); } //term filter: Hashtable termViews = new Hashtable(); termViews.put(TERM_OPTION_ALL, rb.getString("list.allTerms")); // bjones86 - SAK-23256 List<AcademicSession> aSessions = setTermListForContext(context, state, false, false); if (aSessions != null) { for (AcademicSession s : aSessions) { termViews.put(s.getTitle(), s.getTitle()); } } // sort the keys in the termViews lookup List<String> termViewKeys = Collections.list(termViews.keys()); Collections.sort(termViewKeys); context.put("termViewKeys", termViewKeys); context.put("termViews", termViews); // default term view if (state.getAttribute(STATE_TERM_VIEW_SELECTED) == null) { state.setAttribute(STATE_TERM_VIEW_SELECTED, TERM_OPTION_ALL); if (ServerConfigurationService.getBoolean(SAK_PROP_AUTO_FILTER_TERM, Boolean.FALSE)) { // SAK-28059 auto filter term to use the most current term List<AcademicSession> currentTerms = cms.getCurrentAcademicSessions(); // current terms are sorted by start date we will just take the first if (!currentTerms.isEmpty()) { int termIndex = termViewKeys.indexOf(currentTerms.get(0).getTitle()); if (termIndex > -1) { state.setAttribute(STATE_TERM_VIEW_SELECTED, termViewKeys.get(termIndex)); context.put("viewTermSelected", termViewKeys.get(termIndex)); } } } } else { context.put("viewTermSelected", (String) state.getAttribute(STATE_TERM_VIEW_SELECTED)); } if (termViews.size() == 1) { //this means the terms are empty, only the default option exist context.put("hideTermFilter", true); } else { context.put("hideTermFilter", false); } String search = (String) state.getAttribute(STATE_SEARCH); context.put("search_term", search); sortedBy = (String) state.getAttribute(SORTED_BY); if (sortedBy == null) { state.setAttribute(SORTED_BY, SortType.TITLE_ASC.toString()); sortedBy = SortType.TITLE_ASC.toString(); } sortedAsc = (String) state.getAttribute(SORTED_ASC); if (sortedAsc == null) { sortedAsc = Boolean.TRUE.toString(); state.setAttribute(SORTED_ASC, sortedAsc); } if (sortedBy != null) context.put("currentSortedBy", sortedBy); if (sortedAsc != null) context.put("currentSortAsc", sortedAsc); String portalUrl = ServerConfigurationService.getPortalUrl(); context.put("portalUrl", portalUrl); List<Site> allSites = prepPage(state); state.setAttribute(STATE_SITES, allSites); context.put("sites", allSites); context.put("totalPageNumber", Integer.valueOf(totalPageNumber(state))); context.put("searchString", state.getAttribute(STATE_SEARCH)); context.put("form_search", FORM_SEARCH); context.put("formPageNumber", FORM_PAGE_NUMBER); context.put("prev_page_exists", state.getAttribute(STATE_PREV_PAGE_EXISTS)); context.put("next_page_exists", state.getAttribute(STATE_NEXT_PAGE_EXISTS)); context.put("current_page", state.getAttribute(STATE_CURRENT_PAGE)); // put the service in the context (used for allow update calls on // each site) context.put("service", SiteService.getInstance()); context.put("sortby_title", SortType.TITLE_ASC.toString()); context.put("sortby_id", SortType.ID_ASC.toString()); context.put("show_id_column", ServerConfigurationService.getBoolean("site.setup.showSiteIdColumn", false)); context.put("sortby_type", SortType.TYPE_ASC.toString()); context.put("sortby_createdby", SortType.CREATED_BY_ASC.toString()); context.put("sortby_publish", SortType.PUBLISHED_ASC.toString()); context.put("sortby_createdon", SortType.CREATED_ON_ASC.toString()); context.put("sortby_softlydeleted", SortType.SOFTLY_DELETED_ASC.toString()); // default to be no paging context.put("paged", Boolean.FALSE); Menu bar2 = new MenuImpl(portlet, data, (String) state.getAttribute(STATE_ACTION)); // add the search commands addSearchMenus(bar2, state); context.put("menu2", bar2); pagingInfoToContext(state, context); //SAK-22438 if user can add one of these site types then they can see the link to add a new site boolean allowAddSite = false; if (SiteService.allowAddCourseSite()) { allowAddSite = true; } else if (SiteService.allowAddPortfolioSite()) { allowAddSite = true; } else if (SiteService.allowAddProjectSite()) { allowAddSite = true; } context.put("allowAddSite", allowAddSite); //SAK-23468 put create variables into context addSiteCreationValuesIntoContext(context, state); return (String) getContext(data).get("template") + TEMPLATE[0]; case 1: /* * buildContextForTemplate chef_site-type.vm * */ List types = (List) state.getAttribute(STATE_SITE_TYPES); List<String> mTypes = siteTypeProvider.getTypesForSiteCreation(); if (mTypes != null && !mTypes.isEmpty()) { types.addAll(mTypes); } context.put("siteTypes", types); context.put("templateControls", ServerConfigurationService.getString("templateControls", "")); // put selected/default site type into context String typeSelected = (String) state.getAttribute(STATE_TYPE_SELECTED); context.put("typeSelected", state.getAttribute(STATE_TYPE_SELECTED) != null ? state.getAttribute(STATE_TYPE_SELECTED) : types.get(0)); // bjones86 - SAK-23256 Boolean hasTerms = Boolean.FALSE; List<AcademicSession> termList = setTermListForContext(context, state, true, true); // true => only if (termList != null && termList.size() > 0) { hasTerms = Boolean.TRUE; } context.put(CONTEXT_HAS_TERMS, hasTerms); // upcoming terms setSelectedTermForContext(context, state, STATE_TERM_SELECTED); // template site setTemplateListForContext(context, state); return (String) getContext(data).get("template") + TEMPLATE[1]; case 4: /* * buildContextForTemplate chef_site-editToolGroups.vm * */ state.removeAttribute(STATE_TOOL_GROUP_LIST); String type = (String) state.getAttribute(STATE_SITE_TYPE); setTypeIntoContext(context, type); Map<String, List> groupTools = getTools(state, type, site); state.setAttribute(STATE_TOOL_GROUP_LIST, groupTools); // information related to LTI tools buildLTIToolContextForTemplate(context, state, site, true); if (SecurityService.isSuperUser()) { context.put("superUser", Boolean.TRUE); } else { context.put("superUser", Boolean.FALSE); } // save all lists to context pageOrderToolTitleIntoContext(context, state, type, (site == null), site == null ? null : site.getProperties() .getProperty(SiteConstants.SITE_PROPERTY_OVERRIDE_HIDE_PAGEORDER_SITE_TYPES)); Boolean checkToolGroupHome = (Boolean) state.getAttribute(STATE_TOOL_HOME_SELECTED); context.put("check_home", checkToolGroupHome); context.put("ltitool_id_prefix", LTITOOL_ID_PREFIX); context.put("serverName", ServerConfigurationService.getServerName()); context.put("sites", SiteService.getSites(org.sakaiproject.site.api.SiteService.SelectionType.UPDATE, null, null, null, SortType.TITLE_ASC, null)); context.put("import", state.getAttribute(STATE_IMPORT)); context.put("importSites", state.getAttribute(STATE_IMPORT_SITES)); if (site != null) { MathJaxEnabler.addMathJaxSettingsToEditToolsContext(context, site, state); // SAK-22384 context.put("SiteTitle", site.getTitle()); context.put("existSite", Boolean.TRUE); context.put("backIndex", "12"); // back to site info list page } else { context.put("existSite", Boolean.FALSE); context.put("backIndex", "13"); // back to new site information page } context.put("homeToolId", TOOL_ID_HOME); context.put("toolsByGroup", (LinkedHashMap<String, List>) state.getAttribute(STATE_TOOL_GROUP_LIST)); context.put("toolGroupMultiples", getToolGroupMultiples(state, (List) state.getAttribute(STATE_TOOL_REGISTRATION_LIST))); return (String) getContext(data).get("template") + TEMPLATE[4]; case 8: /* * buildContextForTemplate chef_site-siteDeleteConfirm.vm * */ String site_title = NULL_STRING; String[] removals = (String[]) state.getAttribute(STATE_SITE_REMOVALS); List remove = new Vector(); String user = SessionManager.getCurrentSessionUserId(); String workspace = SiteService.getUserSiteId(user); // Are we attempting to softly delete a site. boolean softlyDeleting = ServerConfigurationService.getBoolean("site.soft.deletion", false); if (removals != null && removals.length != 0) { for (int i = 0; i < removals.length; i++) { String id = (String) removals[i]; if (!(id.equals(workspace))) { if (SiteService.allowRemoveSite(id)) { try { // check whether site exists Site removeSite = SiteService.getSite(id); //check site isn't already softly deleted if (softlyDeleting && removeSite.isSoftlyDeleted()) { softlyDeleting = false; } remove.add(removeSite); } catch (IdUnusedException e) { M_log.warn(this + "buildContextForTemplate chef_site-siteDeleteConfirm.vm - IdUnusedException " + id + e.getMessage()); addAlert(state, rb.getFormattedMessage("java.couldntlocate", new Object[] { id })); } } else { addAlert(state, rb.getFormattedMessage("java.couldntdel", new Object[] { site_title })); } } else { addAlert(state, rb.getString("java.yourwork")); } } if (remove.size() == 0) { addAlert(state, rb.getString("java.click")); } } context.put("removals", remove); //check if hard deletes are wanted if (StringUtils.equalsIgnoreCase((String) state.getAttribute(STATE_HARD_DELETE), Boolean.TRUE.toString())) { context.put("hardDelete", true); //SAK-29678 - If it's hard deleted, it's not soft deleted. softlyDeleting = false; } //check if soft deletes are activated context.put("softDelete", softlyDeleting); return (String) getContext(data).get("template") + TEMPLATE[8]; case 10: /* * buildContextForTemplate chef_site-newSiteConfirm.vm * */ siteInfo = (SiteInfo) state.getAttribute(STATE_SITE_INFO); String siteType = (String) state.getAttribute(STATE_SITE_TYPE); if (SiteTypeUtil.isCourseSite(siteType)) { context.put("isCourseSite", Boolean.TRUE); context.put("disableCourseSelection", ServerConfigurationService.getString("disable.course.site.skin.selection", "false") .equals("true") ? Boolean.TRUE : Boolean.FALSE); context.put("isProjectSite", Boolean.FALSE); putSelectedProviderCourseIntoContext(context, state); if (state.getAttribute(STATE_CM_AUTHORIZER_SECTIONS) != null) { context.put("selectedAuthorizerCourse", state.getAttribute(STATE_CM_AUTHORIZER_SECTIONS)); } if (state.getAttribute(STATE_CM_REQUESTED_SECTIONS) != null) { context.put("selectedRequestedCourse", state.getAttribute(STATE_CM_REQUESTED_SECTIONS)); } if (state.getAttribute(STATE_MANUAL_ADD_COURSE_NUMBER) != null) { int number = ((Integer) state.getAttribute(STATE_MANUAL_ADD_COURSE_NUMBER)).intValue(); context.put("manualAddNumber", Integer.valueOf(number - 1)); context.put("manualAddFields", state.getAttribute(STATE_MANUAL_ADD_COURSE_FIELDS)); } else if (state.getAttribute(STATE_CM_REQUESTED_SECTIONS) != null) { context.put("manualAddNumber", Integer.valueOf(((List) state.getAttribute(STATE_CM_REQUESTED_SECTIONS)).size())); } context.put("skins", state.getAttribute(STATE_ICONS)); if (StringUtils.trimToNull(siteInfo.getIconUrl()) != null) { context.put("selectedIcon", siteInfo.getIconUrl()); } } else { context.put("isCourseSite", Boolean.FALSE); if (SiteTypeUtil.isProjectSite(siteType)) { context.put("isProjectSite", Boolean.TRUE); } if (StringUtils.trimToNull(siteInfo.iconUrl) != null) { context.put("iconUrl", siteInfo.iconUrl); } } context.put("siteUrls", getSiteUrlsForAliasIds(siteInfo.siteRefAliases)); context.put("title", siteInfo.title); context.put("description", siteInfo.description); context.put("short_description", siteInfo.short_description); context.put("siteContactName", siteInfo.site_contact_name); context.put("siteContactEmail", siteInfo.site_contact_email); /// site language information String locale_string_selected = (String) state.getAttribute("locale_string"); if (locale_string_selected == "" || locale_string_selected == null) context.put("locale_string_selected", ""); else { Locale locale_selected = getLocaleFromString(locale_string_selected); context.put("locale_string_selected", locale_selected); } // put tool selection into context toolSelectionIntoContext(context, state, siteType, null, null/*site.getProperties().getProperty(SiteConstants.SITE_PROPERTY_OVERRIDE_HIDE_PAGEORDER_SITE_TYPES)*/); context.put("check_home", state.getAttribute(STATE_TOOL_HOME_SELECTED)); context.put("emailId", state.getAttribute(STATE_TOOL_EMAIL_ADDRESS)); context.put("serverName", ServerConfigurationService.getServerName()); context.put("include", Boolean.valueOf(siteInfo.include)); context.put("published", Boolean.valueOf(siteInfo.published)); context.put("joinable", Boolean.valueOf(siteInfo.joinable)); context.put("joinerRole", siteInfo.joinerRole); context.put("additionalAccess", getAdditionRoles(siteInfo)); // bjones86 - SAK-24423 - add joinable site settings to context JoinableSiteSettings.addJoinableSiteSettingsToNewSiteConfirmContext(context, siteInfo); context.put("importSiteTools", state.getAttribute(STATE_IMPORT_SITE_TOOL)); context.put("siteService", SiteService.getInstance()); // those manual inputs context.put("form_requiredFields", sectionFieldProvider.getRequiredFields()); context.put("fieldValues", state.getAttribute(STATE_MANUAL_ADD_COURSE_FIELDS)); context.put("fromArchive", state.getAttribute(STATE_UPLOADED_ARCHIVE_NAME)); return (String) getContext(data).get("template") + TEMPLATE[10]; case 12: /* * buildContextForTemplate chef_site-siteInfo-list.vm * */ // put the link for downloading participant putPrintParticipantLinkIntoContext(context, data, site); context.put("userDirectoryService", UserDirectoryService.getInstance()); try { siteProperties = site.getProperties(); siteType = site.getType(); if (siteType != null) { state.setAttribute(STATE_SITE_TYPE, siteType); } if (site.getProviderGroupId() != null) { M_log.debug("site has provider"); context.put("hasProviderSet", Boolean.TRUE); } else { M_log.debug("site has no provider"); context.put("hasProviderSet", Boolean.FALSE); } boolean isMyWorkspace = false; if (SiteService.isUserSite(site.getId())) { if (SiteService.getSiteUserId(site.getId()).equals(SessionManager.getCurrentSessionUserId())) { isMyWorkspace = true; context.put("siteUserId", SiteService.getSiteUserId(site.getId())); } } context.put("isMyWorkspace", Boolean.valueOf(isMyWorkspace)); String siteId = site.getId(); if (state.getAttribute(STATE_ICONS) != null) { List skins = (List) state.getAttribute(STATE_ICONS); for (int i = 0; i < skins.size(); i++) { MyIcon s = (MyIcon) skins.get(i); if (StringUtils.equals(s.getUrl(), site.getIconUrl())) { context.put("siteUnit", s.getName()); break; } } } context.put("siteFriendlyUrls", getSiteUrlsForSite(site)); context.put("siteDefaultUrl", getDefaultSiteUrl(siteId)); context.put("siteId", site.getId()); context.put("siteIcon", site.getIconUrl()); context.put("siteTitle", site.getTitle()); context.put("siteDescription", site.getDescription()); context.put("siteId", site.getId()); if (unJoinableSiteTypes != null && !unJoinableSiteTypes.contains(siteType)) { context.put("siteJoinable", Boolean.valueOf(site.isJoinable())); context.put("allowUnjoin", SiteService.allowUnjoinSite(site.getId())); } // Is the current user a member context.put("siteUserMember", site.getUserRole(UserDirectoryService.getCurrentUser().getId()) != null); if (site.isPublished()) { context.put("published", Boolean.TRUE); } else { context.put("published", Boolean.FALSE); context.put("owner", site.getCreatedBy().getSortName()); } Time creationTime = site.getCreatedTime(); if (creationTime != null) { context.put("siteCreationDate", creationTime.toStringLocalFull()); } boolean allowUpdateSite = SiteService.allowUpdateSite(siteId); context.put("allowUpdate", Boolean.valueOf(allowUpdateSite)); boolean allowUpdateGroupMembership = SiteService.allowUpdateGroupMembership(siteId); context.put("allowUpdateGroupMembership", Boolean.valueOf(allowUpdateGroupMembership)); boolean allowUpdateSiteMembership = SiteService.allowUpdateSiteMembership(siteId); context.put("allowUpdateSiteMembership", Boolean.valueOf(allowUpdateSiteMembership)); context.put("additionalAccess", getAdditionRoles(site)); Menu b = new MenuImpl(portlet, data, (String) state.getAttribute(STATE_ACTION)); if (allowUpdateSite) { // Site modified by information User siteModifiedBy = site.getModifiedBy(); Time siteModifiedTime = site.getModifiedTime(); if (siteModifiedBy != null) { context.put("siteModifiedBy", siteModifiedBy.getSortName()); } if (siteModifiedTime != null) { context.put("siteModifiedTime", siteModifiedTime.toStringLocalFull()); } // top menu bar if (!isMyWorkspace) { b.add(new MenuEntry(rb.getString("java.editsite"), "doMenu_edit_site_info")); } b.add(new MenuEntry(rb.getString("java.edittools"), "doMenu_edit_site_tools")); // if the page order helper is available, not // stealthed and not hidden, show the link if (notStealthOrHiddenTool("sakai-site-pageorder-helper")) { // in particular, need to check site types for showing the tool or not if (isPageOrderAllowed(siteType, siteProperties .getProperty(SiteConstants.SITE_PROPERTY_OVERRIDE_HIDE_PAGEORDER_SITE_TYPES))) { b.add(new MenuEntry(rb.getString("java.orderpages"), "doPageOrderHelper")); } } } if (allowUpdateSiteMembership) { // show add participant menu if (!isMyWorkspace) { // if the add participant helper is available, not // stealthed and not hidden, show the link if (notStealthOrHiddenTool("sakai-site-manage-participant-helper")) { b.add(new MenuEntry(rb.getString("java.addp"), "doParticipantHelper")); } // show the Edit Class Roster menu if (ServerConfigurationService.getBoolean("site.setup.allow.editRoster", true) && siteType != null && SiteTypeUtil.isCourseSite(siteType)) { b.add(new MenuEntry(rb.getString("java.editc"), "doMenu_siteInfo_editClass")); } } } if (allowUpdateGroupMembership) { // show Manage Groups menu if (!isMyWorkspace && (ServerConfigurationService.getString("wsetup.group.support") == "" || ServerConfigurationService.getString("wsetup.group.support") .equalsIgnoreCase(Boolean.TRUE.toString()))) { // show the group toolbar unless configured // to not support group // if the manage group helper is available, not // stealthed and not hidden, show the link // read the helper name from configuration variable: wsetup.group.helper.name // the default value is: "sakai-site-manage-group-section-role-helper" // the older version of group helper which is not section/role aware is named:"sakai-site-manage-group-helper" String groupHelper = ServerConfigurationService.getString("wsetup.group.helper.name", "sakai-site-manage-group-section-role-helper"); if (setHelper("wsetup.groupHelper", groupHelper, state, STATE_GROUP_HELPER_ID)) { b.add(new MenuEntry(rb.getString("java.group"), "doManageGroupHelper")); } } } if (allowUpdateSite) { // show add parent sites menu if (!isMyWorkspace) { if (notStealthOrHiddenTool("sakai-site-manage-link-helper")) { b.add(new MenuEntry(rb.getString("java.link"), "doLinkHelper")); } if (notStealthOrHiddenTool("sakai.basiclti.admin.helper")) { b.add(new MenuEntry(rb.getString("java.external"), "doExternalHelper")); } } } if (allowUpdateSite) { if (!isMyWorkspace) { List<String> providedSiteTypes = siteTypeProvider.getTypes(); boolean isProvidedType = false; if (siteType != null && providedSiteTypes.contains(siteType)) { isProvidedType = true; } if (!isProvidedType) { // hide site access for provided site types // type of sites b.add(new MenuEntry(rb.getString("java.siteaccess"), "doMenu_edit_site_access")); // hide site duplicate and import if (SiteService.allowAddSite(null) && ServerConfigurationService .getBoolean("site.setup.allowDuplicateSite", true)) { b.add(new MenuEntry(rb.getString("java.duplicate"), "doMenu_siteInfo_duplicate")); } List updatableSites = SiteService.getSites( org.sakaiproject.site.api.SiteService.SelectionType.UPDATE, null, null, null, SortType.TITLE_ASC, null); // import link should be visible even if only one // site if (updatableSites.size() > 0) { //a configuration param for showing/hiding Import From Site with Clean Up String importFromSite = ServerConfigurationService.getString("clean.import.site", Boolean.TRUE.toString()); if (importFromSite.equalsIgnoreCase("true")) { b.add(new MenuEntry(rb.getString("java.import"), "doMenu_siteInfo_importSelection")); } else { b.add(new MenuEntry(rb.getString("java.import"), "doMenu_siteInfo_import")); } // a configuration param for // showing/hiding import // from file choice String importFromFile = ServerConfigurationService .getString("site.setup.import.file", Boolean.TRUE.toString()); if (importFromFile.equalsIgnoreCase("true")) { // htripath: June // 4th added as per // Kris and changed // desc of above b.add(new MenuEntry(rb.getString("java.importFile"), "doAttachmentsMtrlFrmFile")); } } } } } if (allowUpdateSite) { // show add parent sites menu if (!isMyWorkspace) { boolean eventLog = "true" .equals(ServerConfigurationService.getString("user_audit_log_display", "true")); if (notStealthOrHiddenTool("sakai.useraudit") && eventLog) { b.add(new MenuEntry(rb.getString("java.userAuditEventLog"), "doUserAuditEventLog")); } } } if (b.size() > 0) { // add the menus to vm context.put("menu", b); } if (state.getAttribute(IMPORT_QUEUED) != null) { context.put("importQueued", true); state.removeAttribute(IMPORT_QUEUED); if (StringUtils.isBlank(UserDirectoryService.getCurrentUser().getEmail()) || !ServerConfigurationService.getBoolean(SAK_PROP_IMPORT_NOTIFICATION, true)) { context.put("importQueuedNoEmail", true); } } if (((String) state.getAttribute(STATE_SITE_MODE)).equalsIgnoreCase(SITE_MODE_SITESETUP)) { // editing from worksite setup tool context.put("fromWSetup", Boolean.TRUE); if (state.getAttribute(STATE_PREV_SITE) != null) { context.put("prevSite", state.getAttribute(STATE_PREV_SITE)); } if (state.getAttribute(STATE_NEXT_SITE) != null) { context.put("nextSite", state.getAttribute(STATE_NEXT_SITE)); } } else { context.put("fromWSetup", Boolean.FALSE); } // allow view roster? boolean allowViewRoster = SiteService.allowViewRoster(siteId); if (allowViewRoster) { context.put("viewRoster", Boolean.TRUE); } else { context.put("viewRoster", Boolean.FALSE); } // set participant list if (allowUpdateSite || allowViewRoster || allowUpdateSiteMembership) { Collection participantsCollection = getParticipantList(state); sortedBy = (String) state.getAttribute(SORTED_BY); sortedAsc = (String) state.getAttribute(SORTED_ASC); if (sortedBy == null) { state.setAttribute(SORTED_BY, SiteConstants.SORTED_BY_PARTICIPANT_NAME); sortedBy = SiteConstants.SORTED_BY_PARTICIPANT_NAME; } if (sortedAsc == null) { sortedAsc = Boolean.TRUE.toString(); state.setAttribute(SORTED_ASC, sortedAsc); } if (sortedBy != null) context.put("currentSortedBy", sortedBy); if (sortedAsc != null) context.put("currentSortAsc", sortedAsc); context.put("participantListSize", Integer.valueOf(participantsCollection.size())); context.put("participantList", prepPage(state)); pagingInfoToContext(state, context); } context.put("include", Boolean.valueOf(site.isPubView())); // site contact information String contactName = siteProperties.getProperty(Site.PROP_SITE_CONTACT_NAME); String contactEmail = siteProperties.getProperty(Site.PROP_SITE_CONTACT_EMAIL); if (contactName == null && contactEmail == null) { User u = site.getCreatedBy(); String email = u.getEmail(); if (email != null) { contactEmail = u.getEmail(); } contactName = u.getDisplayName(); } if (contactName != null) { context.put("contactName", contactName); } if (contactEmail != null) { context.put("contactEmail", contactEmail); } if (SiteTypeUtil.isCourseSite(siteType)) { context.put("isCourseSite", Boolean.TRUE); coursesIntoContext(state, context, site); context.put("term", siteProperties.getProperty(Site.PROP_SITE_TERM)); } else { context.put("isCourseSite", Boolean.FALSE); } Collection<Group> groups = null; if (ServerConfigurationService.getBoolean("wsetup.group.support.summary", true)) { if ((allowUpdateSite || allowUpdateGroupMembership) && (!isMyWorkspace && ServerConfigurationService.getBoolean("wsetup.group.support", true))) { // show all site groups groups = site.getGroups(); } else { // show groups that the current user is member of groups = site.getGroupsWithMember(UserDirectoryService.getCurrentUser().getId()); } } if (groups != null) { // filter out only those groups that are manageable by site-info List<Group> filteredGroups = new ArrayList<Group>(); List<Group> filteredSections = new ArrayList<Group>(); Collection<String> viewMembershipGroups = new ArrayList<String>(); Collection<String> unjoinableGroups = new ArrayList<String>(); for (Group g : groups) { Object gProp = g.getProperties().getProperty(g.GROUP_PROP_WSETUP_CREATED); if (gProp != null && gProp.equals(Boolean.TRUE.toString())) { filteredGroups.add(g); } else { filteredSections.add(g); } Object vProp = g.getProperties().getProperty(g.GROUP_PROP_VIEW_MEMBERS); if (vProp != null && vProp.equals(Boolean.TRUE.toString())) { viewMembershipGroups.add(g.getId()); } Object joinableProp = g.getProperties().getProperty(g.GROUP_PROP_JOINABLE_SET); Object unjoinableProp = g.getProperties().getProperty(g.GROUP_PROP_JOINABLE_UNJOINABLE); if (joinableProp != null && !"".equals(joinableProp.toString()) && unjoinableProp != null && unjoinableProp.equals(Boolean.TRUE.toString()) && g.getMember(UserDirectoryService.getCurrentUser().getId()) != null) { unjoinableGroups.add(g.getId()); } } Collections.sort(filteredGroups, new Comparator<Group>() { public int compare(Group o1, Group o2) { return o1.getTitle().compareToIgnoreCase(o2.getTitle()); } }); context.put("groups", filteredGroups); Collections.sort(filteredSections, new Comparator<Group>() { public int compare(Group o1, Group o2) { return o1.getTitle().compareToIgnoreCase(o2.getTitle()); } }); context.put("sections", filteredSections); context.put("viewMembershipGroups", viewMembershipGroups); context.put("unjoinableGroups", unjoinableGroups); } //joinable groups: List<JoinableGroup> joinableGroups = new ArrayList<JoinableGroup>(); if (site.getGroups() != null) { //find a list of joinable-sets this user is already a member of //in order to not display those groups as options Set<String> joinableSetsMember = new HashSet<String>(); for (Group group : site.getGroupsWithMember(UserDirectoryService.getCurrentUser().getId())) { String joinableSet = group.getProperties().getProperty(group.GROUP_PROP_JOINABLE_SET); if (joinableSet != null && !"".equals(joinableSet.trim())) { joinableSetsMember.add(joinableSet); } } for (Group group : site.getGroups()) { String joinableSet = group.getProperties().getProperty(group.GROUP_PROP_JOINABLE_SET); if (joinableSet != null && !"".equals(joinableSet.trim()) && !joinableSetsMember.contains(joinableSet)) { String reference = group.getReference(); String title = group.getTitle(); int max = 0; try { max = Integer.parseInt( group.getProperties().getProperty(group.GROUP_PROP_JOINABLE_SET_MAX)); } catch (Exception e) { } boolean preview = Boolean.valueOf( group.getProperties().getProperty(group.GROUP_PROP_JOINABLE_SET_PREVIEW)); String groupMembers = ""; int size = 0; try { AuthzGroup g = authzGroupService.getAuthzGroup(group.getReference()); Collection<Member> gMembers = g != null ? g.getMembers() : new Vector<Member>(); size = gMembers.size(); if (size > 0) { Set<String> hiddenUsers = new HashSet<String>(); boolean viewHidden = viewHidden = SecurityService.unlock("roster.viewHidden", site.getReference()) || SecurityService.unlock("roster.viewHidden", g.getReference()); if (!SiteService.allowViewRoster(siteId) && !viewHidden) { //find hidden users in this group: //add hidden users to set so we can filter them out Set<String> memberIds = new HashSet<String>(); for (Member member : gMembers) { memberIds.add(member.getUserId()); } hiddenUsers = privacyManager.findHidden(site.getReference(), memberIds); } for (Iterator<Member> gItr = gMembers.iterator(); gItr.hasNext();) { Member p = (Member) gItr.next(); // exclude those user with provided roles and rosters String userId = p.getUserId(); if (!hiddenUsers.contains(userId)) { try { User u = UserDirectoryService.getUser(userId); if (!"".equals(groupMembers)) { groupMembers += ", "; } groupMembers += u.getDisplayName(); } catch (Exception e) { M_log.debug(this + "joinablegroups: cannot find user with id " + userId); // need to remove the group member size--; } } } } } catch (GroupNotDefinedException e) { M_log.debug(this + "joinablegroups: cannot find group " + group.getReference()); } joinableGroups.add(new JoinableGroup(reference, title, joinableSet, size, max, groupMembers, preview)); } } if (joinableGroups.size() > 0) { Collections.sort(joinableGroups, new Comparator<JoinableGroup>() { public int compare(JoinableGroup g1, JoinableGroup g2) { return g1.getTitle().compareToIgnoreCase(g2.getTitle()); } }); context.put("joinableGroups", joinableGroups); } } } catch (Exception e) { M_log.error(this + " buildContextForTemplate chef_site-siteInfo-list.vm ", e); } roles = getRoles(state); context.put("roles", roles); // SAK-23257 - add the allowed roles to the context for UI rendering context.put(VM_ALLOWED_ROLES_DROP_DOWN, SiteParticipantHelper.getAllowedRoles(site.getType(), roles)); // will have the choice to active/inactive user or not String activeInactiveUser = ServerConfigurationService.getString("activeInactiveUser", Boolean.FALSE.toString()); if (activeInactiveUser.equalsIgnoreCase("true")) { context.put("activeInactiveUser", Boolean.TRUE); } else { context.put("activeInactiveUser", Boolean.FALSE); } // UVa add realm object to context so we can provide last modified time realmId = SiteService.siteReference(site.getId()); try { AuthzGroup realm = authzGroupService.getAuthzGroup(realmId); context.put("realmModifiedTime", realm.getModifiedTime().toStringLocalFullZ()); } catch (GroupNotDefinedException e) { M_log.warn(this + " IdUnusedException " + realmId); } // SAK-22384 mathjax support MathJaxEnabler.addMathJaxSettingsToSiteInfoContext(context, site, state); return (String) getContext(data).get("template") + TEMPLATE[12]; case 13: /* * buildContextForTemplate chef_site-siteInfo-editInfo.vm * */ if (site != null) { // revising a existing site's tool context.put("existingSite", Boolean.TRUE); context.put("continue", "14"); ResourcePropertiesEdit props = site.getPropertiesEdit(); String locale_string = StringUtils.trimToEmpty(props.getProperty(PROP_SITE_LANGUAGE)); context.put("locale_string", locale_string); } else { // new site context.put("existingSite", Boolean.FALSE); context.put("continue", "4"); // get the system default as locale string context.put("locale_string", ""); } boolean displaySiteAlias = displaySiteAlias(); context.put("displaySiteAlias", Boolean.valueOf(displaySiteAlias)); if (displaySiteAlias) { context.put(FORM_SITE_URL_BASE, getSiteBaseUrl()); context.put(FORM_SITE_ALIAS, siteInfo.getFirstAlias()); } siteType = (String) state.getAttribute(STATE_SITE_TYPE); context.put("type", siteType); context.put("siteTitleEditable", Boolean.valueOf(siteTitleEditable(state, siteType))); context.put("titleMaxLength", state.getAttribute(STATE_SITE_TITLE_MAX)); if (SiteTypeUtil.isCourseSite(siteType)) { context.put("isCourseSite", Boolean.TRUE); context.put("isProjectSite", Boolean.FALSE); boolean hasRosterAttached = putSelectedProviderCourseIntoContext(context, state); List<SectionObject> cmRequestedList = (List<SectionObject>) state .getAttribute(STATE_CM_REQUESTED_SECTIONS); if (cmRequestedList != null) { context.put("cmRequestedSections", cmRequestedList); if (!hasRosterAttached && cmRequestedList.size() > 0) { hasRosterAttached = true; } } List<SectionObject> cmAuthorizerSectionList = (List<SectionObject>) state .getAttribute(STATE_CM_AUTHORIZER_SECTIONS); if (cmAuthorizerSectionList != null) { context.put("cmAuthorizerSections", cmAuthorizerSectionList); if (!hasRosterAttached && cmAuthorizerSectionList.size() > 0) { hasRosterAttached = true; } } if (state.getAttribute(STATE_MANUAL_ADD_COURSE_NUMBER) != null) { int number = ((Integer) state.getAttribute(STATE_MANUAL_ADD_COURSE_NUMBER)).intValue(); context.put("manualAddNumber", Integer.valueOf(number - 1)); context.put("manualAddFields", state.getAttribute(STATE_MANUAL_ADD_COURSE_FIELDS)); if (!hasRosterAttached) { hasRosterAttached = true; } } else { if (site != null) if (!hasRosterAttached) { hasRosterAttached = coursesIntoContext(state, context, site); } else { coursesIntoContext(state, context, site); } if (courseManagementIsImplemented()) { } else { context.put("templateIndex", "37"); } } context.put("hasRosterAttached", Boolean.valueOf(hasRosterAttached)); if (StringUtils.trimToNull(siteInfo.term) == null) { if (site != null) { // existing site siteInfo.term = site.getProperties().getProperty(Site.PROP_SITE_TERM); } else { // creating new site AcademicSession t = (AcademicSession) state.getAttribute(STATE_TERM_SELECTED); siteInfo.term = t != null ? t.getEid() : ""; } } context.put("selectedTerm", siteInfo.term != null ? siteInfo.term : ""); } else { context.put("isCourseSite", Boolean.FALSE); if (SiteTypeUtil.isProjectSite(siteType)) { context.put("isProjectSite", Boolean.TRUE); } if (StringUtils.trimToNull(siteInfo.iconUrl) != null) { context.put(FORM_ICON_URL, siteInfo.iconUrl); } } // about skin and icon selection skinIconSelection(context, state, SiteTypeUtil.isCourseSite(siteType), site, siteInfo); // those manual inputs context.put("form_requiredFields", sectionFieldProvider.getRequiredFields()); context.put("fieldValues", state.getAttribute(STATE_MANUAL_ADD_COURSE_FIELDS)); context.put("title", siteInfo.title); context.put(FORM_SITE_URL_BASE, getSiteBaseUrl()); context.put(FORM_SITE_ALIAS, siteInfo.getFirstAlias()); context.put("description", siteInfo.description); context.put("short_description", siteInfo.short_description); context.put("form_site_contact_name", siteInfo.site_contact_name); context.put("form_site_contact_email", siteInfo.site_contact_email); context.put("site_aliases", state.getAttribute(FORM_SITEINFO_ALIASES)); context.put("site_url_base", state.getAttribute(FORM_SITEINFO_URL_BASE)); context.put("site_aliases_editable", aliasesEditable(state, site == null ? null : site.getReference())); context.put("site_alias_assignable", aliasAssignmentForNewSitesEnabled(state)); // available languages in sakai.properties List locales = getPrefLocales(); context.put("locales", locales); // SAK-22384 mathjax support MathJaxEnabler.addMathJaxSettingsToSiteInfoContext(context, site, state); return (String) getContext(data).get("template") + TEMPLATE[13]; case 14: /* * buildContextForTemplate chef_site-siteInfo-editInfoConfirm.vm * */ siteInfo = (SiteInfo) state.getAttribute(STATE_SITE_INFO); context.put("displaySiteAlias", Boolean.valueOf(displaySiteAlias())); siteProperties = site.getProperties(); siteType = (String) state.getAttribute(STATE_SITE_TYPE); if (SiteTypeUtil.isCourseSite(siteType)) { context.put("isCourseSite", Boolean.TRUE); context.put("siteTerm", siteInfo.term); } else { context.put("isCourseSite", Boolean.FALSE); } // about skin and icon selection skinIconSelection(context, state, SiteTypeUtil.isCourseSite(siteType), site, siteInfo); context.put("oTitle", site.getTitle()); context.put("title", siteInfo.title); // get updated language String new_locale_string = (String) state.getAttribute("locale_string"); if (new_locale_string == "" || new_locale_string == null) context.put("new_locale", ""); else { Locale new_locale = getLocaleFromString(new_locale_string); context.put("new_locale", new_locale); } // get site language saved ResourcePropertiesEdit props = site.getPropertiesEdit(); String oLocale_string = props.getProperty(PROP_SITE_LANGUAGE); if (oLocale_string == "" || oLocale_string == null) context.put("oLocale", ""); else { Locale oLocale = getLocaleFromString(oLocale_string); context.put("oLocale", oLocale); } context.put("description", siteInfo.description); context.put("oDescription", site.getDescription()); context.put("short_description", siteInfo.short_description); context.put("oShort_description", site.getShortDescription()); context.put("skin", siteInfo.iconUrl); context.put("oSkin", site.getIconUrl()); context.put("skins", state.getAttribute(STATE_ICONS)); context.put("oIcon", site.getIconUrl()); context.put("icon", siteInfo.iconUrl); context.put("include", siteInfo.include); context.put("oInclude", Boolean.valueOf(site.isPubView())); context.put("name", siteInfo.site_contact_name); context.put("oName", siteProperties.getProperty(Site.PROP_SITE_CONTACT_NAME)); context.put("email", siteInfo.site_contact_email); context.put("oEmail", siteProperties.getProperty(Site.PROP_SITE_CONTACT_EMAIL)); context.put("siteUrls", getSiteUrlsForAliasIds(siteInfo.siteRefAliases)); context.put("oSiteUrls", getSiteUrlsForSite(site)); // SAK-22384 mathjax support MathJaxEnabler.addMathJaxSettingsToSiteInfoContext(context, site, state); return (String) getContext(data).get("template") + TEMPLATE[14]; case 15: /* * buildContextForTemplate chef_site-addRemoveFeatureConfirm.vm * */ context.put("title", site.getTitle()); site_type = (String) state.getAttribute(STATE_SITE_TYPE); boolean myworkspace_site = false; if (SiteService.isUserSite(site.getId())) { if (SiteService.getSiteUserId(site.getId()).equals(SessionManager.getCurrentSessionUserId())) { myworkspace_site = true; site_type = "myworkspace"; } } String overridePageOrderSiteTypes = site.getProperties() .getProperty(SiteConstants.SITE_PROPERTY_OVERRIDE_HIDE_PAGEORDER_SITE_TYPES); // put tool selection into context toolSelectionIntoContext(context, state, site_type, site.getId(), overridePageOrderSiteTypes); MathJaxEnabler.addMathJaxSettingsToEditToolsConfirmationContext(context, site, state, STATE_TOOL_REGISTRATION_TITLE_LIST); // SAK-22384 return (String) getContext(data).get("template") + TEMPLATE[15]; case 18: /* * buildContextForTemplate chef_siteInfo-editAccess.vm * */ List publicChangeableSiteTypes = (List) state.getAttribute(STATE_PUBLIC_CHANGEABLE_SITE_TYPES); context.put("authAllowed", ServerConfigurationService.getBoolean("sitemanage.grant.auth", false)); context.put("anonAllowed", ServerConfigurationService.getBoolean("sitemanage.grant.anon", false)); if (site != null) { // editing existing site context.put("site", site); siteType = state.getAttribute(STATE_SITE_TYPE) != null ? (String) state.getAttribute(STATE_SITE_TYPE) : null; if (siteType != null && publicChangeableSiteTypes.contains(siteType)) { context.put("publicChangeable", Boolean.TRUE); } else { context.put("publicChangeable", Boolean.FALSE); } context.put("published", state.getAttribute(STATE_SITE_ACCESS_PUBLISH)); context.put("include", state.getAttribute(STATE_SITE_ACCESS_INCLUDE)); context.put("shoppingPeriodInstructorEditable", ServerConfigurationService .getBoolean("delegatedaccess.shopping.instructorEditable", false)); context.put("viewDelegatedAccessUsers", ServerConfigurationService .getBoolean("delegatedaccess.siteaccess.instructorViewable", false)); // bjones86 - SAK-24423 - add joinable site settings to context JoinableSiteSettings.addJoinableSiteSettingsToEditAccessContextWhenSiteIsNotNull(context, state, site, !unJoinableSiteTypes.contains(siteType)); if (siteType != null && !unJoinableSiteTypes.contains(siteType)) { // site can be set as joinable context.put("disableJoinable", Boolean.FALSE); if (state.getAttribute(STATE_JOINABLE) == null) { state.setAttribute(STATE_JOINABLE, Boolean.valueOf(site.isJoinable())); } if (state.getAttribute(STATE_JOINABLE) != null) { context.put("joinable", state.getAttribute(STATE_JOINABLE)); } if (state.getAttribute(STATE_JOINERROLE) != null) { context.put("joinerRole", state.getAttribute(STATE_JOINERROLE)); } } else { // site cannot be set as joinable context.put("disableJoinable", Boolean.TRUE); } Map<String, AdditionalRole> access = getAdditionalAccess(site); addAccess(context, access); // bjones86 - SAK-23257 context.put("roles", getJoinerRoles(site.getReference(), state, site.getType())); } else { // In the site creation process... siteInfo = (SiteInfo) state.getAttribute(STATE_SITE_INFO); if (siteInfo.site_type != null && publicChangeableSiteTypes.contains(siteInfo.site_type)) { context.put("publicChangeable", Boolean.TRUE); } else { context.put("publicChangeable", Boolean.FALSE); } context.put("include", Boolean.valueOf(siteInfo.getInclude())); context.put("published", Boolean.valueOf(siteInfo.getPublished())); if (siteInfo.site_type != null && !unJoinableSiteTypes.contains(siteInfo.site_type)) { // site can be set as joinable context.put("disableJoinable", Boolean.FALSE); context.put("joinable", Boolean.valueOf(siteInfo.joinable)); context.put("joinerRole", siteInfo.joinerRole); } else { // site cannot be set as joinable context.put("disableJoinable", Boolean.TRUE); } // bjones86 - SAK-24423 - add joinable site settings to context JoinableSiteSettings.addJoinableSiteSettingsToEditAccessContextWhenSiteIsNull(context, siteInfo, true); // the template site, if using one Site templateSite = (Site) state.getAttribute(STATE_TEMPLATE_SITE); // use the type's template, if defined String realmTemplate = "!site.template"; // if create based on template, use the roles from the template if (templateSite != null) { realmTemplate = SiteService.siteReference(templateSite.getId()); } else if (siteInfo.site_type != null) { realmTemplate = realmTemplate + "." + siteInfo.site_type; } try { AuthzGroup r = authzGroupService.getAuthzGroup(realmTemplate); // bjones86 - SAK-23257 context.put("roles", getJoinerRoles(r.getId(), state, null)); } catch (GroupNotDefinedException e) { try { AuthzGroup rr = authzGroupService.getAuthzGroup("!site.template"); // bjones86 - SAK-23257 context.put("roles", getJoinerRoles(rr.getId(), state, null)); } catch (GroupNotDefinedException ee) { } } Map<String, AdditionalRole> additionalRoles = loadAdditionalRoles(); for (AdditionalRole role : additionalRoles.values()) { if (siteInfo.additionalRoles.contains(role.getId())) { role.granted = true; } } addAccess(context, additionalRoles); context.put("continue", "10"); siteType = (String) state.getAttribute(STATE_SITE_TYPE); setTypeIntoContext(context, siteType); } return (String) getContext(data).get("template") + TEMPLATE[18]; case 26: /* * buildContextForTemplate chef_site-modifyENW.vm * */ site_type = (String) state.getAttribute(STATE_SITE_TYPE); boolean existingSite = site != null ? true : false; if (existingSite) { // revising a existing site's tool context.put("existingSite", Boolean.TRUE); context.put("continue", "15"); } else { // new site context.put("existingSite", Boolean.FALSE); context.put("continue", "18"); } context.put(STATE_TOOL_REGISTRATION_LIST, state.getAttribute(STATE_TOOL_REGISTRATION_LIST)); toolRegistrationSelectedList = (List) state.getAttribute(STATE_TOOL_REGISTRATION_SELECTED_LIST); context.put(STATE_TOOL_REGISTRATION_SELECTED_LIST, toolRegistrationSelectedList); // String toolId's // all info related to multiple tools multipleToolIntoContext(context, state); // put the lti tool selection into context if (state.getAttribute(STATE_LTITOOL_SELECTED_LIST) != null) { HashMap<String, Map<String, Object>> currentLtiTools = (HashMap<String, Map<String, Object>>) state .getAttribute(STATE_LTITOOL_SELECTED_LIST); for (Map.Entry<String, Map<String, Object>> entry : currentLtiTools.entrySet()) { Map<String, Object> toolMap = entry.getValue(); String toolId = entry.getKey(); // get the proper html for tool input String ltiToolId = toolMap.get("id").toString(); String[] contentToolModel = m_ltiService.getContentModel(Long.valueOf(ltiToolId)); // attach the ltiToolId to each model attribute, so that we could have the tool configuration page for multiple tools for (int k = 0; k < contentToolModel.length; k++) { contentToolModel[k] = ltiToolId + "_" + contentToolModel[k]; } Map<String, Object> ltiTool = m_ltiService.getTool(Long.valueOf(ltiToolId)); String formInput = m_ltiService.formInput(ltiTool, contentToolModel); toolMap.put("formInput", formInput); currentLtiTools.put(ltiToolId, toolMap); } context.put("ltiTools", currentLtiTools); context.put("ltiService", m_ltiService); context.put("oldLtiTools", state.getAttribute(STATE_LTITOOL_EXISTING_SELECTED_LIST)); } context.put("toolManager", ToolManager.getInstance()); AcademicSession thisAcademicSession = (AcademicSession) state.getAttribute(STATE_TERM_SELECTED); String emailId = null; boolean prePopulateEmail = ServerConfigurationService.getBoolean("wsetup.mailarchive.prepopulate.email", true); if (prePopulateEmail == true && state.getAttribute(STATE_TOOL_EMAIL_ADDRESS) == null) { if (thisAcademicSession != null) { String siteTitle1 = siteInfo.title.replaceAll("[(].*[)]", ""); siteTitle1 = siteTitle1.trim(); siteTitle1 = siteTitle1.replaceAll(" ", "-"); emailId = siteTitle1; } else { emailId = StringUtils.deleteWhitespace(siteInfo.title); } } else { emailId = (String) state.getAttribute(STATE_TOOL_EMAIL_ADDRESS); } if (emailId != null) { context.put("emailId", emailId); } context.put("serverName", ServerConfigurationService.getServerName()); context.put("oldSelectedTools", state.getAttribute(STATE_TOOL_REGISTRATION_OLD_SELECTED_LIST)); context.put("homeToolId", TOOL_ID_HOME); context.put("maxToolTitleLength", MAX_TOOL_TITLE_LENGTH); return (String) getContext(data).get("template") + TEMPLATE[26]; case 27: { /* * buildContextForTemplate chef_site-importSites.vm * * This is called before the list of tools to choose the content to import from (when merging) is presented. * This is also called in the new site workflow if re-using content from an existing site * */ existingSite = site != null ? true : false; site_type = (String) state.getAttribute(STATE_SITE_TYPE); // define the tools available for import. defaults to those tools in the 'destination' site List<String> importableToolsIdsInDestinationSite = (List) state .getAttribute(STATE_TOOL_REGISTRATION_SELECTED_LIST); if (existingSite) { // revising a existing site's tool context.put("continue", "12"); context.put("step", "2"); context.put("currentSite", site); // if the site exists, there may be other tools available for import importableToolsIdsInDestinationSite = getToolsAvailableForImport(state, importableToolsIdsInDestinationSite); } else { // new site, go to edit access page if (fromENWModifyView(state)) { context.put("continue", "26"); } else { context.put("continue", "18"); } } // list of all tools that participate in the archive/merge process that are in the site selected to import from List<Site> importSites = new ArrayList<Site>( ((Hashtable) state.getAttribute(STATE_IMPORT_SITES)).keySet()); List<String> allImportableToolIdsInOriginalSites = getToolsInSitesAvailableForImport(importSites); context.put("existingSite", Boolean.valueOf(existingSite)); //sort the list of all tools by title and extract into a list of toolIds //we then use this as the basis for sorting the other toolId lists List<MyTool> allTools = (List<MyTool>) state.getAttribute(STATE_TOOL_REGISTRATION_LIST); Collections.sort(allTools, new Comparator<MyTool>() { public int compare(MyTool t1, MyTool t2) { return t1.getTitle().compareTo(t2.getTitle()); } }); final List<String> sortedToolIds = new ArrayList<String>(); for (MyTool m : allTools) { sortedToolIds.add(m.getId()); } //use the above sorted list as the basis to sort the following two toolId lists Collections.sort(allImportableToolIdsInOriginalSites, new Comparator<String>() { public int compare(String s1, String s2) { return Integer.compare(sortedToolIds.indexOf(s1), sortedToolIds.indexOf(s2)); } }); Collections.sort(importableToolsIdsInDestinationSite, new Comparator<String>() { public int compare(String s1, String s2) { return Integer.compare(sortedToolIds.indexOf(s1), sortedToolIds.indexOf(s2)); } }); context.put(STATE_TOOL_REGISTRATION_LIST, allTools); //if option is enabled, show the import for all tools in the original site, not just the ones in this site //otherwise, only import content for the tools that already exist in the 'destination' site boolean addMissingTools = isAddMissingToolsOnImportEnabled(); //helper var to hold the list we use for the selectedTools context variable, as we use it for the alternate toolnames too List<String> selectedTools = new ArrayList<>(); if (addMissingTools) { selectedTools = allImportableToolIdsInOriginalSites; context.put("selectedTools", selectedTools); //set tools in destination site into context so we can markup the lists and show which ones are new context.put("toolsInDestinationSite", importableToolsIdsInDestinationSite); } else { //just just the ones in the destination site selectedTools = importableToolsIdsInDestinationSite; context.put("selectedTools", selectedTools); } //get all known tool names from the sites selected to import from (importSites) and the selectedTools list Map<String, Set<String>> toolNames = this.getToolNames(selectedTools, importSites); //filter this list so its just the alternate ones and turn it into a string for the UI Map<String, String> alternateToolTitles = new HashMap<>(); for (MyTool myTool : allTools) { String toolId = myTool.getId(); String toolTitle = myTool.getTitle(); Set<String> allToolNames = toolNames.get(toolId); if (allToolNames != null) { allToolNames.remove(toolTitle); //if we have something left then we have alternates, so process them if (!allToolNames.isEmpty()) { alternateToolTitles.put(toolId, StringUtils.join(allToolNames, ", ")); } } } context.put("alternateToolTitlesMap", alternateToolTitles); //build a map of sites and tools in those sites that have content Map<String, Set<String>> siteToolsWithContent = this.getSiteImportToolsWithContent(importSites, selectedTools); context.put("siteToolsWithContent", siteToolsWithContent); // set the flag for the UI context.put("addMissingTools", addMissingTools); context.put("importSites", state.getAttribute(STATE_IMPORT_SITES)); context.put("importSitesTools", state.getAttribute(STATE_IMPORT_SITE_TOOL)); context.put("check_home", state.getAttribute(STATE_TOOL_HOME_SELECTED)); context.put("importSupportedTools", allImportableToolIdsInOriginalSites); context.put("hideImportedContent", ServerConfigurationService.getBoolean("content.import.hidden", false)); if (ServerConfigurationService.getBoolean("site-manage.importoption.siteinfo", false)) { try { String siteInfoToolTitle = ToolManager.getTool(SITE_INFO_TOOL_ID).getTitle(); context.put("siteInfoToolTitle", siteInfoToolTitle); } catch (Exception e) { } } return (String) getContext(data).get("template") + TEMPLATE[27]; } case 60: { /* * buildContextForTemplate chef_site-importSitesMigrate.vm * * This is called before the list of tools to choose the content to import from (when replacing) is presented. * */ existingSite = site != null ? true : false; site_type = (String) state.getAttribute(STATE_SITE_TYPE); // define the tools available for import. defaults to those tools in the 'destination' site List<String> importableToolsIdsInDestinationSite = (List) state .getAttribute(STATE_TOOL_REGISTRATION_SELECTED_LIST); if (existingSite) { // revising a existing site's tool context.put("continue", "12"); context.put("back", "28"); context.put("step", "2"); context.put("currentSite", site); // if the site exists, there may be other tools available for import importableToolsIdsInDestinationSite = getToolsAvailableForImport(state, importableToolsIdsInDestinationSite); } else { // new site, go to edit access page context.put("back", "4"); if (fromENWModifyView(state)) { context.put("continue", "26"); } else { context.put("continue", "18"); } //use the toolId list for the new site we are creating importableToolsIdsInDestinationSite = (List<String>) state .getAttribute(STATE_TOOL_REGISTRATION_SELECTED_LIST); } // list of all tools that participate in the archive/merge process that are in the site selected to import from List<Site> importSites = new ArrayList<Site>( ((Hashtable) state.getAttribute(STATE_IMPORT_SITES)).keySet()); List<String> allImportableToolIdsInOriginalSites = getToolsInSitesAvailableForImport(importSites); //sort the list of all tools by title and extract into a list of toolIds //we then use this as the basis for sorting the other toolId lists List<MyTool> allTools = (List<MyTool>) state.getAttribute(STATE_TOOL_REGISTRATION_LIST); Collections.sort(allTools, new Comparator<MyTool>() { public int compare(MyTool t1, MyTool t2) { return t1.getTitle().compareTo(t2.getTitle()); } }); final List<String> sortedToolIds = new ArrayList<String>(); for (MyTool m : allTools) { sortedToolIds.add(m.getId()); } //use the above sorted list as the basis to sort the following two toolId lists Collections.sort(allImportableToolIdsInOriginalSites, new Comparator<String>() { public int compare(String s1, String s2) { return Integer.compare(sortedToolIds.indexOf(s1), sortedToolIds.indexOf(s2)); } }); Collections.sort(importableToolsIdsInDestinationSite, new Comparator<String>() { public int compare(String s1, String s2) { return Integer.compare(sortedToolIds.indexOf(s1), sortedToolIds.indexOf(s2)); } }); //ensure this is the original tool list and set the sorted list back into context. context.put(STATE_TOOL_REGISTRATION_LIST, allTools); state.setAttribute(STATE_TOOL_REGISTRATION_SELECTED_LIST, state.getAttribute(STATE_TOOL_REGISTRATION_SELECTED_LIST)); //if option is enabled, import into ALL tools, not just the ones in this site //otherwise, only import content for the tools that already exist in the 'destination' site boolean addMissingTools = isAddMissingToolsOnImportEnabled(); //helper var to hold the list we use for the selectedTools context variable, as we use it for the alternate toolnames too List<String> selectedTools = new ArrayList<>(); if (addMissingTools) { selectedTools = allImportableToolIdsInOriginalSites; context.put("selectedTools", selectedTools); //set tools in destination site into context so we can markup the lists and show which ones are new context.put("toolsInDestinationSite", importableToolsIdsInDestinationSite); } else { selectedTools = importableToolsIdsInDestinationSite; //just just the ones in the destination site context.put("selectedTools", selectedTools); } //get all known tool names from the sites selected to import from (importSites) and the selectedTools list Map<String, Set<String>> toolNames = this.getToolNames(selectedTools, importSites); //filter this list so its just the alternate ones and turn it into a string for the UI Map<String, String> alternateToolTitles = new HashMap<>(); for (MyTool myTool : allTools) { String toolId = myTool.getId(); String toolTitle = myTool.getTitle(); Set<String> allToolNames = toolNames.get(toolId); if (allToolNames != null) { allToolNames.remove(toolTitle); //if we have something left then we have alternates, so process them if (!allToolNames.isEmpty()) { alternateToolTitles.put(toolId, StringUtils.join(allToolNames, ", ")); } } } context.put("alternateToolTitlesMap", alternateToolTitles); //build a map of sites and tools in those sites that have content Map<String, Set<String>> siteToolsWithContent = this.getSiteImportToolsWithContent(importSites, selectedTools); context.put("siteToolsWithContent", siteToolsWithContent); // set the flag for the UI context.put("addMissingTools", addMissingTools); context.put("importSites", state.getAttribute(STATE_IMPORT_SITES)); context.put("importSitesTools", state.getAttribute(STATE_IMPORT_SITE_TOOL)); context.put("check_home", state.getAttribute(STATE_TOOL_HOME_SELECTED)); context.put("importSupportedTools", allImportableToolIdsInOriginalSites); return (String) getContext(data).get("template") + TEMPLATE[60]; } case 28: /* * buildContextForTemplate chef_siteinfo-import.vm * * This is called before the list of sites to import from is presented * */ putImportSitesInfoIntoContext(context, site, state, false); return (String) getContext(data).get("template") + TEMPLATE[28]; case 58: /* * buildContextForTemplate chef_siteinfo-importSelection.vm * */ putImportSitesInfoIntoContext(context, site, state, false); return (String) getContext(data).get("template") + TEMPLATE[58]; case 59: /* * buildContextForTemplate chef_siteinfo-importMigrate.vm * */ putImportSitesInfoIntoContext(context, site, state, false); return (String) getContext(data).get("template") + TEMPLATE[59]; case 29: /* * buildContextForTemplate chef_siteinfo-duplicate.vm * */ context.put("siteTitle", site.getTitle()); String sType = site.getType(); if (sType != null && SiteTypeUtil.isCourseSite(sType)) { context.put("isCourseSite", Boolean.TRUE); context.put("currentTermId", site.getProperties().getProperty(Site.PROP_SITE_TERM)); // bjones86 - SAK-23256 setTermListForContext(context, state, true, false); // true upcoming only } else { context.put("isCourseSite", Boolean.FALSE); } if (state.getAttribute(SITE_DUPLICATED) == null) { context.put("siteDuplicated", Boolean.FALSE); } else { context.put("siteDuplicated", Boolean.TRUE); context.put("duplicatedName", state.getAttribute(SITE_DUPLICATED_NAME)); } // SAK-20797 - display checkboxes only if sitespecific value exists long quota = getSiteSpecificQuota(site); if (quota > 0) { context.put("hasSiteSpecificQuota", true); context.put("quotaSize", formatSize(quota * 1024)); } else { context.put("hasSiteSpecificQuota", false); } context.put("titleMaxLength", state.getAttribute(STATE_SITE_TITLE_MAX)); return (String) getContext(data).get("template") + TEMPLATE[29]; case 36: /* * buildContextForTemplate chef_site-newSiteCourse.vm */ // SAK-9824 Boolean enableCourseCreationForUser = ServerConfigurationService.getBoolean("site.enableCreateAnyUser", Boolean.FALSE); context.put("enableCourseCreationForUser", enableCourseCreationForUser); if (site != null) { context.put("site", site); context.put("siteTitle", site.getTitle()); List providerCourseList = (List) state.getAttribute(SITE_PROVIDER_COURSE_LIST); coursesIntoContext(state, context, site); // bjones86 - SAK-23256 List<AcademicSession> terms = setTermListForContext(context, state, true, true); // true -> upcoming only AcademicSession t = (AcademicSession) state.getAttribute(STATE_TERM_SELECTED); if (terms != null && terms.size() > 0) { boolean foundTerm = false; for (AcademicSession testTerm : terms) { if (t != null && testTerm.getEid().equals(t.getEid())) { foundTerm = true; break; } } if (!foundTerm) { // if the term is no longer listed in the term list, choose the first term in the list instead t = terms.get(0); } } context.put("term", t); if (t != null) { String userId = UserDirectoryService.getCurrentUser().getEid(); List courses = prepareCourseAndSectionListing(userId, t.getEid(), state); if (courses != null && courses.size() > 0) { Vector notIncludedCourse = new Vector(); // remove included sites for (Iterator i = courses.iterator(); i.hasNext();) { CourseObject c = (CourseObject) i.next(); if (providerCourseList == null || !providerCourseList.contains(c.getEid())) { notIncludedCourse.add(c); } } state.setAttribute(STATE_TERM_COURSE_LIST, notIncludedCourse); } else { state.removeAttribute(STATE_TERM_COURSE_LIST); } } } else { // need to include both list 'cos STATE_CM_AUTHORIZER_SECTIONS // contains sections that doens't belongs to current user and // STATE_ADD_CLASS_PROVIDER_CHOSEN contains section that does - // v2.4 daisyf if (state.getAttribute(STATE_ADD_CLASS_PROVIDER_CHOSEN) != null || state.getAttribute(STATE_CM_AUTHORIZER_SECTIONS) != null) { putSelectedProviderCourseIntoContext(context, state); List<SectionObject> authorizerSectionList = (List<SectionObject>) state .getAttribute(STATE_CM_AUTHORIZER_SECTIONS); if (authorizerSectionList != null) { List authorizerList = (List) state.getAttribute(STATE_CM_AUTHORIZER_LIST); //authorizerList is a list of SectionObject /* String userId = null; if (authorizerList != null) { userId = (String) authorizerList.get(0); } List list2 = prepareSectionObject( authorizerSectionList, userId); */ ArrayList list2 = new ArrayList(); for (int i = 0; i < authorizerSectionList.size(); i++) { SectionObject so = (SectionObject) authorizerSectionList.get(i); list2.add(so.getEid()); } context.put("selectedAuthorizerCourse", list2); } } if (state.getAttribute(STATE_MANUAL_ADD_COURSE_NUMBER) != null) { context.put("selectedManualCourse", Boolean.TRUE); } context.put("term", (AcademicSession) state.getAttribute(STATE_TERM_SELECTED)); context.put("currentUserId", (String) state.getAttribute(STATE_CM_CURRENT_USERID)); context.put("form_additional", (String) state.getAttribute(FORM_ADDITIONAL)); context.put("authorizers", getAuthorizers(state, STATE_CM_AUTHORIZER_LIST)); } if (((String) state.getAttribute(STATE_SITE_MODE)).equalsIgnoreCase(SITE_MODE_SITESETUP)) { context.put("backIndex", "1"); } else if (((String) state.getAttribute(STATE_SITE_MODE)).equalsIgnoreCase(SITE_MODE_SITEINFO)) { context.put("backIndex", ""); } List ll = (List) state.getAttribute(STATE_TERM_COURSE_LIST); context.put("termCourseList", state.getAttribute(STATE_TERM_COURSE_LIST)); // SAK-29000 Boolean isAuthorizationRequired = ServerConfigurationService.getBoolean(SAK_PROP_REQUIRE_AUTHORIZER, Boolean.TRUE); context.put(VM_ADD_ROSTER_AUTH_REQUIRED, isAuthorizationRequired); // added for 2.4 -daisyf context.put("campusDirectory", getCampusDirectory()); context.put("userId", state.getAttribute(STATE_INSTRUCTOR_SELECTED) != null ? (String) state.getAttribute(STATE_INSTRUCTOR_SELECTED) : UserDirectoryService.getCurrentUser().getId()); /* * for measuring how long it takes to load sections java.util.Date * date = new java.util.Date(); M_log.debug("***2. finish at: * "+date); M_log.debug("***3. userId:"+(String) state * .getAttribute(STATE_INSTRUCTOR_SELECTED)); */ context.put("basedOnTemplate", state.getAttribute(STATE_TEMPLATE_SITE) != null ? Boolean.TRUE : Boolean.FALSE); context.put("publishTemplate", (Boolean) state.getAttribute(STATE_TEMPLATE_PUBLISH)); // bjones86 - SAK-21706 context.put(CONTEXT_SKIP_COURSE_SECTION_SELECTION, ServerConfigurationService.getBoolean(SAK_PROP_SKIP_COURSE_SECTION_SELECTION, Boolean.FALSE)); context.put(CONTEXT_SKIP_MANUAL_COURSE_CREATION, ServerConfigurationService.getBoolean(SAK_PROP_SKIP_MANUAL_COURSE_CREATION, Boolean.FALSE)); context.put("siteType", state.getAttribute(STATE_TYPE_SELECTED)); // SAK-28990 remove continue with no roster if ("true".equalsIgnoreCase( ServerConfigurationService.getString(SAK_PROP_CONT_NO_ROSTER_ENABLED, "true"))) { context.put(VM_CONT_NO_ROSTER_ENABLED, Boolean.TRUE); } else { context.put(VM_CONT_NO_ROSTER_ENABLED, Boolean.FALSE); } return (String) getContext(data).get("template") + TEMPLATE[36]; case 37: /* * buildContextForTemplate chef_site-newSiteCourseManual.vm */ if (site != null) { context.put("site", site); context.put("siteTitle", site.getTitle()); coursesIntoContext(state, context, site); } buildInstructorSectionsList(state, params, context); context.put("form_requiredFields", sectionFieldProvider.getRequiredFields()); context.put("form_additional", siteInfo.additional); context.put("form_title", siteInfo.title); context.put("form_description", siteInfo.description); context.put("officialAccountName", ServerConfigurationService.getString("officialAccountName", "")); if (state.getAttribute(STATE_SITE_QUEST_UNIQNAME) == null) { context.put("value_uniqname", getAuthorizers(state, STATE_SITE_QUEST_UNIQNAME)); } int number = 1; if (state.getAttribute(STATE_MANUAL_ADD_COURSE_NUMBER) != null) { number = ((Integer) state.getAttribute(STATE_MANUAL_ADD_COURSE_NUMBER)).intValue(); context.put("currentNumber", Integer.valueOf(number)); } context.put("currentNumber", Integer.valueOf(number)); context.put("listSize", number > 0 ? Integer.valueOf(number - 1) : 0); if (state.getAttribute(STATE_MANUAL_ADD_COURSE_FIELDS) != null && ((List) state.getAttribute(STATE_MANUAL_ADD_COURSE_FIELDS)).size() > 0) { context.put("fieldValues", state.getAttribute(STATE_MANUAL_ADD_COURSE_FIELDS)); } putSelectedProviderCourseIntoContext(context, state); if (state.getAttribute(STATE_CM_REQUESTED_SECTIONS) != null) { List l = (List) state.getAttribute(STATE_CM_REQUESTED_SECTIONS); context.put("cmRequestedSections", l); } if (state.getAttribute(STATE_SITE_MODE).equals(SITE_MODE_SITEINFO)) { context.put("editSite", Boolean.TRUE); context.put("cmSelectedSections", state.getAttribute(STATE_CM_SELECTED_SECTIONS)); } if (site == null) { if (state.getAttribute(STATE_AUTO_ADD) != null) { context.put("autoAdd", Boolean.TRUE); } } isFutureTermSelected(state); context.put("isFutureTerm", state.getAttribute(STATE_FUTURE_TERM_SELECTED)); context.put("weeksAhead", ServerConfigurationService.getString("roster.available.weeks.before.term.start", "0")); context.put("basedOnTemplate", state.getAttribute(STATE_TEMPLATE_SITE) != null ? Boolean.TRUE : Boolean.FALSE); context.put("publishTemplate", (Boolean) state.getAttribute(STATE_TEMPLATE_PUBLISH)); context.put("requireAuthorizer", ServerConfigurationService.getString(SAK_PROP_REQUIRE_AUTHORIZER, "true").equals("true") ? Boolean.TRUE : Boolean.FALSE); // bjones86 - SAK-21706/SAK-23255 context.put(CONTEXT_IS_ADMIN, SecurityService.isSuperUser()); context.put(CONTEXT_SKIP_COURSE_SECTION_SELECTION, ServerConfigurationService.getBoolean(SAK_PROP_SKIP_COURSE_SECTION_SELECTION, Boolean.FALSE)); context.put(CONTEXT_FILTER_TERMS, ServerConfigurationService.getBoolean(SAK_PROP_FILTER_TERMS, Boolean.FALSE)); return (String) getContext(data).get("template") + TEMPLATE[37]; case 42: /* * buildContextForTemplate chef_site-type-confirm.vm * */ siteInfo = (SiteInfo) state.getAttribute(STATE_SITE_INFO); context.put("title", siteInfo.title); context.put("description", siteInfo.description); context.put("short_description", siteInfo.short_description); toolRegistrationList = (Vector) state.getAttribute(STATE_PROJECT_TOOL_LIST); toolRegistrationSelectedList = (List) state.getAttribute(STATE_TOOL_REGISTRATION_SELECTED_LIST); context.put(STATE_TOOL_REGISTRATION_SELECTED_LIST, toolRegistrationSelectedList); // String toolId's context.put(STATE_TOOL_REGISTRATION_LIST, toolRegistrationList); // %%% // use // Tool context.put("check_home", state.getAttribute(STATE_TOOL_HOME_SELECTED)); context.put("emailId", state.getAttribute(STATE_TOOL_EMAIL_ADDRESS)); context.put("serverName", ServerConfigurationService.getServerName()); context.put("include", Boolean.valueOf(siteInfo.include)); return (String) getContext(data).get("template") + TEMPLATE[42]; case 43: /* * buildContextForTemplate chef_siteInfo-editClass.vm * */ bar = new MenuImpl(portlet, data, (String) state.getAttribute(STATE_ACTION)); if (SiteService.allowAddSite(null)) { bar.add(new MenuEntry(rb.getString("java.addclasses"), "doMenu_siteInfo_addClass")); } context.put("menu", bar); context.put("siteTitle", site.getTitle()); coursesIntoContext(state, context, site); return (String) getContext(data).get("template") + TEMPLATE[43]; case 44: /* * buildContextForTemplate chef_siteInfo-addCourseConfirm.vm * */ context.put("siteTitle", site.getTitle()); coursesIntoContext(state, context, site); putSelectedProviderCourseIntoContext(context, state); if (state.getAttribute(STATE_CM_SELECTED_SECTIONS) != null) { context.put("cmSelectedSections", state.getAttribute(STATE_CM_SELECTED_SECTIONS)); } if (state.getAttribute(STATE_CM_REQUESTED_SECTIONS) != null) { context.put("cmRequestedSections", state.getAttribute(STATE_CM_REQUESTED_SECTIONS)); } if (state.getAttribute(STATE_MANUAL_ADD_COURSE_NUMBER) != null) { int addNumber = ((Integer) state.getAttribute(STATE_MANUAL_ADD_COURSE_NUMBER)).intValue() - 1; context.put("manualAddNumber", Integer.valueOf(addNumber)); context.put("requestFields", state.getAttribute(STATE_MANUAL_ADD_COURSE_FIELDS)); context.put("backIndex", "37"); } else { context.put("backIndex", "36"); } // those manual inputs context.put("form_requiredFields", sectionFieldProvider.getRequiredFields()); context.put("fieldValues", state.getAttribute(STATE_MANUAL_ADD_COURSE_FIELDS)); return (String) getContext(data).get("template") + TEMPLATE[44]; // htripath - import materials from classic case 45: /* * buildContextForTemplate chef_siteInfo-importMtrlMaster.vm * */ return (String) getContext(data).get("template") + TEMPLATE[45]; case 46: /* * buildContextForTemplate chef_siteInfo-importMtrlCopy.vm * */ // this is for list display in listbox context.put("allZipSites", state.getAttribute(ALL_ZIP_IMPORT_SITES)); context.put("finalZipSites", state.getAttribute(FINAL_ZIP_IMPORT_SITES)); // zip file // context.put("zipreffile",state.getAttribute(CLASSIC_ZIP_FILE_NAME)); return (String) getContext(data).get("template") + TEMPLATE[46]; case 47: /* * buildContextForTemplate chef_siteInfo-importMtrlCopyConfirm.vm * */ context.put("finalZipSites", state.getAttribute(FINAL_ZIP_IMPORT_SITES)); return (String) getContext(data).get("template") + TEMPLATE[47]; case 48: /* * buildContextForTemplate chef_siteInfo-importMtrlCopyConfirm.vm * */ context.put("finalZipSites", state.getAttribute(FINAL_ZIP_IMPORT_SITES)); return (String) getContext(data).get("template") + TEMPLATE[48]; // case 49, 50, 51 have been implemented in helper mode case 53: { /* * build context for chef_site-findCourse.vm */ AcademicSession t = (AcademicSession) state.getAttribute(STATE_TERM_SELECTED); List cmLevels = (List) state.getAttribute(STATE_CM_LEVELS), selections = (List) state.getAttribute(STATE_CM_LEVEL_SELECTIONS); if (cmLevels == null) { cmLevels = getCMLevelLabels(state); } List<SectionObject> selectedSect = (List<SectionObject>) state.getAttribute(STATE_CM_SELECTED_SECTION); List<SectionObject> requestedSections = (List<SectionObject>) state .getAttribute(STATE_CM_REQUESTED_SECTIONS); if (courseManagementIsImplemented() && cms != null) { context.put("cmsAvailable", Boolean.valueOf(true)); } int cmLevelSize = 0; if (cms == null || !courseManagementIsImplemented() || cmLevels == null || cmLevels.size() < 1) { // TODO: redirect to manual entry: case #37 } else { cmLevelSize = cmLevels.size(); Object levelOpts[] = state.getAttribute(STATE_CM_LEVEL_OPTS) == null ? new Object[cmLevelSize] : (Object[]) state.getAttribute(STATE_CM_LEVEL_OPTS); int numSelections = 0; if (selections != null) { numSelections = selections.size(); } if (numSelections != 0) { // execution will fall through these statements based on number of selections already made if (numSelections == cmLevelSize - 1) { levelOpts[numSelections] = getCMSections((String) selections.get(numSelections - 1)); } else if (numSelections == cmLevelSize - 2) { levelOpts[numSelections] = getCMCourseOfferings( getSelectionString(selections, numSelections), t.getEid()); } else if (numSelections < cmLevelSize) { levelOpts[numSelections] = sortCourseSets( cms.findCourseSets(getSelectionString(selections, numSelections))); } } // always set the top level Set<CourseSet> courseSets = filterCourseSetList(getCourseSet(state)); levelOpts[0] = sortCourseSets(courseSets); // clean further element inside the array for (int i = numSelections + 1; i < cmLevelSize; i++) { levelOpts[i] = null; } context.put("cmLevelOptions", Arrays.asList(levelOpts)); context.put("cmBaseCourseSetLevel", Integer.valueOf((levelOpts.length - 3) >= 0 ? (levelOpts.length - 3) : 0)); // staring from that selection level, the lookup will be for CourseSet, CourseOffering, and Section context.put("maxSelectionDepth", Integer.valueOf(levelOpts.length - 1)); state.setAttribute(STATE_CM_LEVEL_OPTS, levelOpts); } putSelectedProviderCourseIntoContext(context, state); if (state.getAttribute(STATE_MANUAL_ADD_COURSE_NUMBER) != null) { int courseInd = ((Integer) state.getAttribute(STATE_MANUAL_ADD_COURSE_NUMBER)).intValue(); context.put("manualAddNumber", Integer.valueOf(courseInd - 1)); context.put("manualAddFields", state.getAttribute(STATE_MANUAL_ADD_COURSE_FIELDS)); } context.put("term", (AcademicSession) state.getAttribute(STATE_TERM_SELECTED)); context.put("cmLevels", cmLevels); context.put("cmLevelSelections", selections); context.put("selectedCourse", selectedSect); context.put("cmRequestedSections", requestedSections); if (state.getAttribute(STATE_SITE_MODE).equals(SITE_MODE_SITEINFO)) { context.put("editSite", Boolean.TRUE); context.put("cmSelectedSections", state.getAttribute(STATE_CM_SELECTED_SECTIONS)); } if (((String) state.getAttribute(STATE_SITE_MODE)).equalsIgnoreCase(SITE_MODE_SITESETUP)) { if (state.getAttribute(STATE_TERM_COURSE_LIST) != null) { context.put("backIndex", "36"); } else { context.put("backIndex", "1"); } } else if (((String) state.getAttribute(STATE_SITE_MODE)).equalsIgnoreCase(SITE_MODE_SITEINFO)) { context.put("backIndex", "36"); } context.put("authzGroupService", authzGroupService); if (selectedSect != null && !selectedSect.isEmpty() && state.getAttribute(STATE_SITE_QUEST_UNIQNAME) == null) { context.put("value_uniqname", selectedSect.get(0).getAuthorizerString()); } context.put("value_uniqname", state.getAttribute(STATE_SITE_QUEST_UNIQNAME)); context.put("basedOnTemplate", state.getAttribute(STATE_TEMPLATE_SITE) != null ? Boolean.TRUE : Boolean.FALSE); context.put("requireAuthorizer", ServerConfigurationService.getString(SAK_PROP_REQUIRE_AUTHORIZER, "true").equals("true") ? Boolean.TRUE : Boolean.FALSE); // bjones86 - SAK-21706/SAK-23255 context.put(CONTEXT_IS_ADMIN, SecurityService.isSuperUser()); context.put(CONTEXT_SKIP_MANUAL_COURSE_CREATION, ServerConfigurationService.getBoolean(SAK_PROP_SKIP_MANUAL_COURSE_CREATION, Boolean.FALSE)); context.put(CONTEXT_FILTER_TERMS, ServerConfigurationService.getBoolean(SAK_PROP_FILTER_TERMS, Boolean.FALSE)); return (String) getContext(data).get("template") + TEMPLATE[53]; } case 54: /* * build context for chef_site-questions.vm */ SiteTypeQuestions siteTypeQuestions = questionService .getSiteTypeQuestions((String) state.getAttribute(STATE_SITE_TYPE)); if (siteTypeQuestions != null) { context.put("questionSet", siteTypeQuestions); context.put("userAnswers", state.getAttribute(STATE_SITE_SETUP_QUESTION_ANSWER)); } context.put("continueIndex", state.getAttribute(STATE_SITE_SETUP_QUESTION_NEXT_TEMPLATE)); return (String) getContext(data).get("template") + TEMPLATE[54]; case 61: /* * build context for chef_site-importUser.vm */ context.put("toIndex", "12"); // only show those sites with same site type putImportSitesInfoIntoContext(context, site, state, true); return (String) getContext(data).get("template") + TEMPLATE[61]; case 62: /* * build context for chef_site-uploadArchive.vm */ //back to access, continue to confirm context.put("back", "18"); //now go to uploadArchive template return (String) getContext(data).get("template") + TEMPLATE[62]; } // should never be reached return (String) getContext(data).get("template") + TEMPLATE[0]; } private void addAccess(Context context, Map<String, AdditionalRole> access) { boolean disableAdditional = access.size() == 0; context.put("disableAdditional", disableAdditional); if (!disableAdditional) { List<AdditionalRoleGroup> roleSets = sortAdditionalRoles(access); context.put("additionalRoleGroups", roleSets); } } private List<AdditionalRoleGroup> sortAdditionalRoles(Map<String, AdditionalRole> access) { HashMap<String, AdditionalRoleGroup> roleMap = new HashMap<String, AdditionalRoleGroup>(); for (String roleId : access.keySet()) { //take key (role group label) from role prefix (until last dot). //.aaa.eee.iii.roleid => key=.aaa.eee.iii int index = roleId.lastIndexOf("."); String key = (index >= 0) ? roleId.substring(0, index) : ""; AdditionalRoleGroup arg = roleMap.get(key); if (arg == null) { arg = new AdditionalRoleGroup(authzGroupService.getRoleGroupName(key)); roleMap.put(key, arg); } List<AdditionalRole> roles = arg.getRoles(); roles.add(access.get(roleId)); } List<AdditionalRoleGroup> roleSets = new ArrayList<AdditionalRoleGroup>(); roleSets.addAll(roleMap.values()); //order categories by name Collections.sort(roleSets); //order roles in categories by name for (AdditionalRoleGroup roleGroup : roleSets) { Collections.sort(roleGroup.getRoles()); } return roleSets; } private List<String> getAdditionRoles(AuthzGroup realm) { List<String> roles = new ArrayList<String>(); for (Role role : (Set<Role>) realm.getRoles()) { if (!authzGroupService.isRoleAssignable(role.getId())) { roles.add(authzGroupService.getRoleName(role.getId())); } } // Make sure it's always in the same order. Collections.sort(roles); return roles; } private List<String> getAdditionRoles(SiteInfo siteInfo) { List<String> roles = new ArrayList<String>(); for (String roleId : siteInfo.additionalRoles) { roles.add(authzGroupService.getRoleName(roleId)); } // Make sure it's always in the same order. Collections.sort(roles); return roles; } private Map<String, AdditionalRole> getAdditionalAccess(AuthzGroup realm) { // Check for .auth/.anon Map<String, AdditionalRole> additionalRoles = loadAdditionalRoles(); for (Role role : (Set<Role>) realm.getRoles()) { if (!authzGroupService.isRoleAssignable(role.getId())) { AdditionalRole additionalRole = additionalRoles.get(role.getId()); if (additionalRole == null) { additionalRole = new AdditionalRole(); additionalRole.id = role.getId(); additionalRole.name = authzGroupService.getRoleName(role.getId()); additionalRole.editable = false; additionalRoles.put(additionalRole.id, additionalRole); } additionalRole.granted = true; } } return additionalRoles; } /** * Load the possible additional roles for this site. * This should really all be behind an API. * @return */ protected Map<String, AdditionalRole> loadAdditionalRoles() { Map<String, AdditionalRole> additionalRoles = new HashMap<String, AdditionalRole>(); for (String roleId : authzGroupService.getAdditionalRoles()) { AdditionalRole role = new AdditionalRole(); role.id = roleId; role.name = authzGroupService.getRoleName(role.id); role.editable = true; additionalRoles.put(role.id, role); } return additionalRoles; } private void toolSelectionIntoContext(Context context, SessionState state, String siteType, String siteId, String overridePageOrderSiteTypes) { List toolRegistrationList; List toolRegistrationSelectedList; toolRegistrationSelectedList = (List) state.getAttribute(STATE_TOOL_REGISTRATION_SELECTED_LIST); toolRegistrationList = (List) state.getAttribute(STATE_TOOL_REGISTRATION_LIST); context.put(STATE_TOOL_REGISTRATION_LIST, toolRegistrationList); if (toolRegistrationSelectedList != null && toolRegistrationList != null) { // see if any tool is added outside of Site Info tool, which means the tool is outside of the allowed tool set for this site type context.put("extraSelectedToolList", state.getAttribute(STATE_EXTRA_SELECTED_TOOL_LIST)); } // put tool title into context if PageOrderHelper is enabled pageOrderToolTitleIntoContext(context, state, siteType, false, overridePageOrderSiteTypes); context.put("check_home", state.getAttribute(STATE_TOOL_HOME_SELECTED)); context.put("selectedTools", orderToolIds(state, checkNullSiteType(state, siteType, siteId), toolRegistrationSelectedList, false)); context.put("oldSelectedTools", state.getAttribute(STATE_TOOL_REGISTRATION_OLD_SELECTED_LIST)); context.put("oldSelectedHome", state.getAttribute(STATE_TOOL_REGISTRATION_OLD_SELECTED_HOME)); context.put("continueIndex", "12"); if (state.getAttribute(STATE_TOOL_EMAIL_ADDRESS) != null) { context.put("emailId", state.getAttribute(STATE_TOOL_EMAIL_ADDRESS)); } context.put("serverName", ServerConfigurationService.getServerName()); // all info related to multiple tools multipleToolIntoContext(context, state); context.put("homeToolId", TOOL_ID_HOME); // put the lti tools information into context context.put("ltiTools", state.getAttribute(STATE_LTITOOL_SELECTED_LIST)); context.put("oldLtiTools", state.getAttribute(STATE_LTITOOL_EXISTING_SELECTED_LIST)); context.put("ltitool_id_prefix", LTITOOL_ID_PREFIX); } /** * prepare lti tool information in context and state variables * @param context * @param state * @param site * @param updateToolRegistration */ private void buildLTIToolContextForTemplate(Context context, SessionState state, Site site, boolean updateToolRegistration) { List<Map<String, Object>> visibleTools, allTools; // get the visible and all (including stealthed) list of lti tools visibleTools = m_ltiService.getTools(null, null, 0, 0); if (site == null) allTools = visibleTools; else allTools = m_ltiService.getToolsDao(null, null, 0, 0, site.getId()); if (visibleTools != null && !visibleTools.isEmpty()) { HashMap<String, Map<String, Object>> ltiTools = new HashMap<String, Map<String, Object>>(); // get invoke count for all lti tools List<Map<String, Object>> contents = m_ltiService.getContents(null, null, 0, 0); HashMap<String, Map<String, Object>> linkedLtiContents = new HashMap<String, Map<String, Object>>(); for (Map<String, Object> content : contents) { String ltiToolId = content.get(m_ltiService.LTI_TOOL_ID).toString(); String siteId = StringUtils.trimToNull((String) content.get(m_ltiService.LTI_SITE_ID)); if (siteId != null) { // whether the tool is already enabled in site String pstr = (String) content.get(LTIService.LTI_PLACEMENT); if (StringUtils.trimToNull(pstr) != null && site != null) { // the lti tool is enabled in the site ToolConfiguration toolConfig = SiteService.findTool(pstr); if (toolConfig != null && toolConfig.getSiteId().equals(siteId)) { Map<String, Object> m = new HashMap<String, Object>(); Map<String, Object> ltiToolValues = m_ltiService.getTool(Long.valueOf(ltiToolId)); if (ltiToolValues != null) { m.put("toolTitle", ltiToolValues.get(LTIService.LTI_TITLE)); m.put("pageTitle", ltiToolValues.get(LTIService.LTI_PAGETITLE)); m.put(LTIService.LTI_TITLE, (String) content.get(LTIService.LTI_TITLE)); m.put("contentKey", content.get(LTIService.LTI_ID)); linkedLtiContents.put(ltiToolId, m); } } } } } // First search list of visibleTools for those not selected (excluding stealthed tools) for (Map<String, Object> toolMap : visibleTools) { String ltiToolId = toolMap.get("id").toString(); String siteId = StringUtils.trimToNull((String) toolMap.get(m_ltiService.LTI_SITE_ID)); toolMap.put("selected", linkedLtiContents.containsKey(ltiToolId)); if (siteId == null || (site != null && siteId.equals(site.getId()))) { // only show the system-range lti tools (siteId = null) // or site-range lti tools for current site (siteId != null), and current siteId equals to current site's id ltiTools.put(ltiToolId, toolMap); } } // Second search list of allTools for those already selected (including stealthed) for (Map<String, Object> toolMap : allTools) { String ltiToolId = toolMap.get("id").toString(); boolean selected = linkedLtiContents.containsKey(ltiToolId); toolMap.put("selected", selected); if (selected && ltiTools.get(ltiToolId) == null) { ltiTools.put(ltiToolId, toolMap); } } state.setAttribute(STATE_LTITOOL_LIST, ltiTools); state.setAttribute(STATE_LTITOOL_EXISTING_SELECTED_LIST, linkedLtiContents); context.put("ltiTools", ltiTools); context.put("selectedLtiTools", linkedLtiContents); if (updateToolRegistration) { // put the selected lti tool ids into state attribute List<String> idSelected = state.getAttribute(STATE_TOOL_REGISTRATION_SELECTED_LIST) != null ? (List<String>) state.getAttribute(STATE_TOOL_REGISTRATION_SELECTED_LIST) : new ArrayList<String>(); for (String ltiId : linkedLtiContents.keySet()) { // attach the prefix idSelected.add(LTITOOL_ID_PREFIX + ltiId); } state.setAttribute(STATE_TOOL_REGISTRATION_SELECTED_LIST, idSelected); } } } private String getSelectionString(List selections, int numSelections) { StringBuffer eidBuffer = new StringBuffer(); for (int i = 0; i < numSelections; i++) { eidBuffer.append(selections.get(i)).append(","); } String eid = eidBuffer.toString(); // trim off last "," if (eid.endsWith(",")) eid = eid.substring(0, eid.lastIndexOf(",")); return eid; } /** * get CourseSet from CourseManagementService and update state attribute * @param state * @return */ private Set getCourseSet(SessionState state) { Set courseSet = null; if (state.getAttribute(STATE_COURSE_SET) != null) { courseSet = (Set) state.getAttribute(STATE_COURSE_SET); } else { courseSet = cms.getCourseSets(); state.setAttribute(STATE_COURSE_SET, courseSet); } return courseSet; } /** * put customized page title into context during an editing process for an existing site and the PageOrder tool is enabled for this site * @param context * @param state * @param siteType * @param newSite */ private void pageOrderToolTitleIntoContext(Context context, SessionState state, String siteType, boolean newSite, String overrideSitePageOrderSetting) { // check if this is an existing site and PageOrder is enabled for the site. If so, show tool title if (!newSite && notStealthOrHiddenTool("sakai-site-pageorder-helper") && isPageOrderAllowed(siteType, overrideSitePageOrderSetting)) { // the actual page titles context.put(STATE_TOOL_REGISTRATION_TITLE_LIST, state.getAttribute(STATE_TOOL_REGISTRATION_TITLE_LIST)); context.put("allowPageOrderHelper", Boolean.TRUE); } else { context.put("allowPageOrderHelper", Boolean.FALSE); } } /** * Depending on institutional setting, all or part of the CourseSet list will be shown in the dropdown list in find course page * for example, sakai.properties could have following setting: * sitemanage.cm.courseset.categories.count=1 * sitemanage.cm.courseset.categories.1=Department * Hence, only CourseSet object with category of "Department" will be shown * @param courseSets * @return */ private Set<CourseSet> filterCourseSetList(Set<CourseSet> courseSets) { if (ServerConfigurationService.getStrings("sitemanage.cm.courseset.categories") != null) { List<String> showCourseSetTypes = new ArrayList( Arrays.asList(ServerConfigurationService.getStrings("sitemanage.cm.courseset.categories"))); Set<CourseSet> rv = new HashSet<CourseSet>(); for (CourseSet courseSet : courseSets) { if (showCourseSetTypes.contains(courseSet.getCategory())) { rv.add(courseSet); } } courseSets = rv; } return courseSets; } /** * put all info necessary for importing site into context * @param context * @param site */ private void putImportSitesInfoIntoContext(Context context, Site site, SessionState state, boolean ownTypeOnly) { context.put("currentSite", site); context.put("importSiteList", state.getAttribute(STATE_IMPORT_SITES)); context.put("sites", SiteService.getSites(org.sakaiproject.site.api.SiteService.SelectionType.UPDATE, ownTypeOnly ? site.getType() : null, null, null, SortType.TITLE_ASC, null)); } /** * get the titles of list of selected provider courses into context * @param context * @param state * @return true if there is selected provider course, false otherwise */ private boolean putSelectedProviderCourseIntoContext(Context context, SessionState state) { boolean rv = false; if (state.getAttribute(STATE_ADD_CLASS_PROVIDER_CHOSEN) != null) { List<String> providerSectionList = (List<String>) state.getAttribute(STATE_ADD_CLASS_PROVIDER_CHOSEN); context.put("selectedProviderCourse", providerSectionList); context.put("selectedProviderCourseDescription", state.getAttribute(STATE_ADD_CLASS_PROVIDER_DESCRIPTION_CHOSEN)); if (providerSectionList != null && providerSectionList.size() > 0) { // roster attached rv = true; } HashMap<String, String> providerSectionListTitles = new HashMap<String, String>(); if (providerSectionList != null) { for (String providerSectionId : providerSectionList) { try { Section s = cms.getSection(providerSectionId); if (s != null) { providerSectionListTitles.put(s.getEid(), s.getTitle()); } } catch (IdNotFoundException e) { providerSectionListTitles.put(providerSectionId, providerSectionId); M_log.warn("putSelectedProviderCourseIntoContext Cannot find section " + providerSectionId); } } context.put("size", Integer.valueOf(providerSectionList.size() - 1)); } context.put("selectedProviderCourseTitles", providerSectionListTitles); } return rv; } /** * whether the PageOrderHelper is allowed to be shown in this site type * @param siteType * @param overrideSitePageOrderSetting * @return */ private boolean isPageOrderAllowed(String siteType, String overrideSitePageOrderSetting) { if (overrideSitePageOrderSetting != null && Boolean.valueOf(overrideSitePageOrderSetting)) { // site-specific setting, show PageOrder tool return true; } else { // read the setting from sakai properties boolean rv = true; String hidePageOrderSiteTypes = ServerConfigurationService .getString(SiteConstants.SAKAI_PROPERTY_HIDE_PAGEORDER_SITE_TYPES, ""); if (hidePageOrderSiteTypes.length() != 0) { if (new ArrayList<String>(Arrays.asList(StringUtils.split(hidePageOrderSiteTypes, ","))) .contains(siteType)) { rv = false; } } return rv; } } /* * SAK-16600 TooGroupMultiples come from toolregistrationselectedlist * @param state current session * @param list list of all tools * @return set of tools that are multiples */ private Map getToolGroupMultiples(SessionState state, List list) { Set multipleToolIdSet = (Set) state.getAttribute(STATE_MULTIPLE_TOOL_ID_SET); Map multipleToolIdTitleMap = state.getAttribute(STATE_MULTIPLE_TOOL_ID_TITLE_MAP) != null ? (Map) state.getAttribute(STATE_MULTIPLE_TOOL_ID_TITLE_MAP) : new HashMap(); Map<String, List> toolGroupMultiples = new HashMap<String, List>(); if (list != null) { for (Iterator iter = list.iterator(); iter.hasNext();) { String toolId = ((MyTool) iter.next()).getId(); String originId = findOriginalToolId(state, toolId); // is this tool in the list of multipeToolIds? if (multipleToolIdSet.contains(originId)) { // is this the original tool or a multiple having uniqueId+originalToolId? if (!originId.equals(toolId)) { if (!toolGroupMultiples.containsKey(originId)) { toolGroupMultiples.put(originId, new ArrayList()); } List tools = toolGroupMultiples.get(originId); MyTool tool = new MyTool(); tool.id = toolId; tool.title = (String) multipleToolIdTitleMap.get(toolId); // tool comes from toolRegistrationSelectList so selected should be true tool.selected = true; // is a toolMultiple ever *required*? tools.add(tool); // update the tools list for this tool id toolGroupMultiples.put(originId, tools); } } } } return toolGroupMultiples; } private void multipleToolIntoContext(Context context, SessionState state) { // titles for multiple tool instances context.put(STATE_MULTIPLE_TOOL_ID_SET, state.getAttribute(STATE_MULTIPLE_TOOL_ID_SET)); context.put(STATE_MULTIPLE_TOOL_ID_TITLE_MAP, state.getAttribute(STATE_MULTIPLE_TOOL_ID_TITLE_MAP)); context.put(STATE_MULTIPLE_TOOL_CONFIGURATION, state.getAttribute(STATE_MULTIPLE_TOOL_CONFIGURATION)); context.put(STATE_MULTIPLE_TOOL_INSTANCE_SELECTED, state.getAttribute(STATE_MULTIPLE_TOOL_INSTANCE_SELECTED)); } // SAK-23468 If this is after an add site, the private void addSiteCreationValuesIntoContext(Context context, SessionState state) { String siteID = (String) state.getAttribute(STATE_NEW_SITE_STATUS_ID); if (siteID != null) { // make sure this message is only seen immediately after a new site is created. context.put(STATE_NEW_SITE_STATUS_ISPUBLISHED, state.getAttribute(STATE_NEW_SITE_STATUS_ISPUBLISHED)); String siteTitle = (String) state.getAttribute(STATE_NEW_SITE_STATUS_TITLE); context.put(STATE_NEW_SITE_STATUS_TITLE, siteTitle); context.put(STATE_NEW_SITE_STATUS_ID, siteID); // remove the values from state so the values are gone on the next call to chef_site-list //clearNewSiteStateParameters(state); } } // SAK-23468 private void setNewSiteStateParameters(Site site, SessionState state) { if (site != null) { state.setAttribute(STATE_NEW_SITE_STATUS_ISPUBLISHED, Boolean.valueOf(site.isPublished())); state.setAttribute(STATE_NEW_SITE_STATUS_ID, site.getId()); state.setAttribute(STATE_NEW_SITE_STATUS_TITLE, site.getTitle()); } } // SAK-23468 private void clearNewSiteStateParameters(SessionState state) { state.removeAttribute(STATE_NEW_SITE_STATUS_ISPUBLISHED); state.removeAttribute(STATE_NEW_SITE_STATUS_ID); state.removeAttribute(STATE_NEW_SITE_STATUS_TITLE); } /** * show site skin and icon selections or not * @param state * @param site * @param siteInfo */ private void skinIconSelection(Context context, SessionState state, boolean isCourseSite, Site site, SiteInfo siteInfo) { // 1. the skin list // For course site, display skin list based on "disable.course.site.skin.selection" value set with sakai.properties file. The setting defaults to be false. boolean disableCourseSkinChoice = ServerConfigurationService .getString("disable.course.site.skin.selection", "false").equals("true"); // For non-course site, display skin list based on "disable.noncourse.site.skin.selection" value set with sakai.properties file. The setting defaults to be true. boolean disableNonCourseSkinChoice = ServerConfigurationService .getString("disable.noncourse.site.skin.selection", "true").equals("true"); if ((isCourseSite && !disableCourseSkinChoice) || (!isCourseSite && !disableNonCourseSkinChoice)) { context.put("allowSkinChoice", Boolean.TRUE); context.put("skins", state.getAttribute(STATE_ICONS)); } else { context.put("allowSkinChoice", Boolean.FALSE); } if (siteInfo != null && StringUtils.trimToNull(siteInfo.getIconUrl()) != null) { context.put("selectedIcon", siteInfo.getIconUrl()); } else if (site != null && site.getIconUrl() != null) { context.put("selectedIcon", site.getIconUrl()); } } /** * */ public void doPageOrderHelper(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); // pass in the siteId of the site to be ordered (so it can configure // // sites other then the current site) // // pass in the siteId of the site to be ordered (so it can configure // sites other then the current site) SessionManager.getCurrentToolSession().setAttribute(HELPER_ID + ".siteId", ((Site) getStateSite(state)).getId()); // launch the helper startHelper(data.getRequest(), "sakai-site-pageorder-helper"); } /** * Launch the participant Helper Tool -- for adding participant * * @see case 12 * */ public void doParticipantHelper(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); // pass in the siteId of the site to be ordered (so it can configure // sites other then the current site) SessionManager.getCurrentToolSession().setAttribute(HELPER_ID + ".siteId", ((Site) getStateSite(state)).getId()); // launch the helper startHelper(data.getRequest(), "sakai-site-manage-participant-helper"); } /** * Launch the Manage Group helper Tool -- for adding, editing and deleting groups * */ public void doManageGroupHelper(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); // pass in the siteId of the site to be ordered (so it can configure // sites other then the current site) SessionManager.getCurrentToolSession().setAttribute(HELPER_ID + ".siteId", ((Site) getStateSite(state)).getId()); // launch the helper startHelper(data.getRequest(), (String) state.getAttribute(STATE_GROUP_HELPER_ID));//"sakai-site-manage-group-helper"); } /** * Launch the Link Helper Tool -- for setting/clearing parent site * * @see case 12 // TODO * */ public void doLinkHelper(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); // pass in the siteId of the site to be ordered (so it can configure // sites other then the current site) SessionManager.getCurrentToolSession().setAttribute(HELPER_ID + ".siteId", ((Site) getStateSite(state)).getId()); // launch the helper startHelper(data.getRequest(), "sakai-site-manage-link-helper"); } /** * Launch the External Tools Helper -- For managing external tools */ public void doExternalHelper(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); // pass in the siteId of the site to be ordered (so it can configure // sites other then the current site) SessionManager.getCurrentToolSession().setAttribute(HELPER_ID + ".siteId", ((Site) getStateSite(state)).getId()); // launch the helper startHelper(data.getRequest(), "sakai.basiclti.admin.helper"); } public void doUserAuditEventLog(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); // pass in the siteId of the site to be ordered (so it can configure // sites other then the current site) SessionManager.getCurrentToolSession().setAttribute(HELPER_ID + ".siteId", ((Site) getStateSite(state)).getId()); // launch the helper startHelper(data.getRequest(), "sakai.useraudit"); } public boolean setHelper(String helperName, String defaultHelperId, SessionState state, String stateHelperString) { String helperId = ServerConfigurationService.getString(helperName, defaultHelperId); // if the state variable regarding the helper is not set yet, set it with the configured helper id if (state.getAttribute(stateHelperString) == null) { state.setAttribute(stateHelperString, helperId); } if (notStealthOrHiddenTool(helperId)) { return true; } return false; } // htripath: import materials from classic /** * Master import -- for import materials from a file * * @see case 45 * */ public void doAttachmentsMtrlFrmFile(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); // state.setAttribute(FILE_UPLOAD_MAX_SIZE, // ServerConfigurationService.getString("content.upload.max", "1")); state.setAttribute(STATE_TEMPLATE_INDEX, "45"); } // doImportMtrlFrmFile /** * Handle File Upload request * * @see case 46 * @throws Exception */ public void doUpload_Mtrl_Frm_File(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); List allzipList = new Vector(); List finalzipList = new Vector(); List directcopyList = new Vector(); // see if the user uploaded a file FileItem fileFromUpload = null; String fileName = null; fileFromUpload = data.getParameters().getFileItem("file"); String max_file_size_mb = ServerConfigurationService.getString("content.upload.max", "1"); long max_bytes = 1024 * 1024; try { max_bytes = Long.parseLong(max_file_size_mb) * 1024 * 1024; } catch (Exception e) { // if unable to parse an integer from the value // in the properties file, use 1 MB as a default max_file_size_mb = "1"; max_bytes = 1024 * 1024; M_log.error(this + ".doUpload_Mtrl_Frm_File: wrong setting of content.upload.max = " + max_file_size_mb, e); } if (fileFromUpload == null) { // "The user submitted a file to upload but it was too big!" addAlert(state, rb.getFormattedMessage("importFile.size", new Object[] { max_file_size_mb })); } else if (fileFromUpload.getFileName() == null || fileFromUpload.getFileName().length() == 0) { addAlert(state, rb.getString("importFile.choosefile")); } else { //Need some other kind of input stream? ResetOnCloseInputStream fileInput = null; InputStream fileInputStream = null; long fileSize = 0; try { // Write to temp file, this should probably be in the velocity util? File tempFile = null; tempFile = File.createTempFile("importFile", ".tmp"); // Delete temp file when program exits. tempFile.deleteOnExit(); fileInputStream = fileFromUpload.getInputStream(); FileOutputStream outBuf = new FileOutputStream(tempFile); byte[] bytes = new byte[102400]; int read = 0; while ((read = fileInputStream.read(bytes)) != -1) { outBuf.write(bytes, 0, read); } outBuf.flush(); outBuf.close(); fileSize = tempFile.length(); fileInput = new ResetOnCloseInputStream(tempFile); } catch (FileNotFoundException fnfe) { M_log.error("FileNotFoundException creating temp import file", fnfe); } catch (IOException ioe) { M_log.error("IOException creating temp import file", ioe); } finally { IOUtils.closeQuietly(fileInputStream); } if (fileSize >= max_bytes) { addAlert(state, rb.getFormattedMessage("importFile.size", new Object[] { max_file_size_mb })); } else if (fileSize > 0) { if (fileInput != null && importService.isValidArchive(fileInput)) { ImportDataSource importDataSource = importService.parseFromFile(fileInput); Log.info("chef", "Getting import items from manifest."); List lst = importDataSource.getItemCategories(); if (lst != null && lst.size() > 0) { Iterator iter = lst.iterator(); while (iter.hasNext()) { ImportMetadata importdata = (ImportMetadata) iter.next(); // Log.info("chef","Preparing import // item '" + importdata.getId() + "'"); if ((!importdata.isMandatory()) && (importdata.getFileName().endsWith(".xml"))) { allzipList.add(importdata); } else { directcopyList.add(importdata); } } } // set Attributes state.setAttribute(ALL_ZIP_IMPORT_SITES, allzipList); state.setAttribute(FINAL_ZIP_IMPORT_SITES, finalzipList); state.setAttribute(DIRECT_ZIP_IMPORT_SITES, directcopyList); state.setAttribute(CLASSIC_ZIP_FILE_NAME, fileName); state.setAttribute(IMPORT_DATA_SOURCE, importDataSource); state.setAttribute(STATE_TEMPLATE_INDEX, "46"); } else { // uploaded file is not a valid archive addAlert(state, rb.getString("importFile.invalidfile")); } } IOUtils.closeQuietly(fileInput); } } // doImportMtrlFrmFile /** * Handle addition to list request * * @param data */ public void doAdd_MtrlSite(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); ParameterParser params = data.getParameters(); List zipList = (List) state.getAttribute(ALL_ZIP_IMPORT_SITES); List fnlList = (List) state.getAttribute(FINAL_ZIP_IMPORT_SITES); List importSites = new ArrayList(Arrays.asList(params.getStrings("addImportSelected"))); for (int i = 0; i < importSites.size(); i++) { String value = (String) importSites.get(i); fnlList.add(removeItems(value, zipList)); } state.setAttribute(ALL_ZIP_IMPORT_SITES, zipList); state.setAttribute(FINAL_ZIP_IMPORT_SITES, fnlList); state.setAttribute(STATE_TEMPLATE_INDEX, "46"); } // doAdd_MtrlSite /** * Helper class for Add and remove * * @param value * @param items * @return */ public ImportMetadata removeItems(String value, List items) { ImportMetadata result = null; for (int i = 0; i < items.size(); i++) { ImportMetadata item = (ImportMetadata) items.get(i); if (value.equals(item.getId())) { result = (ImportMetadata) items.remove(i); break; } } return result; } /** * Handle the request for remove * * @param data */ public void doRemove_MtrlSite(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); ParameterParser params = data.getParameters(); List zipList = (List) state.getAttribute(ALL_ZIP_IMPORT_SITES); List fnlList = (List) state.getAttribute(FINAL_ZIP_IMPORT_SITES); List importSites = new ArrayList(Arrays.asList(params.getStrings("removeImportSelected"))); for (int i = 0; i < importSites.size(); i++) { String value = (String) importSites.get(i); zipList.add(removeItems(value, fnlList)); } state.setAttribute(ALL_ZIP_IMPORT_SITES, zipList); state.setAttribute(FINAL_ZIP_IMPORT_SITES, fnlList); state.setAttribute(STATE_TEMPLATE_INDEX, "46"); } // doAdd_MtrlSite /** * Handle the request for copy * * @param data */ public void doCopyMtrlSite(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); List fnlList = (List) state.getAttribute(FINAL_ZIP_IMPORT_SITES); state.setAttribute(FINAL_ZIP_IMPORT_SITES, fnlList); state.setAttribute(STATE_TEMPLATE_INDEX, "47"); } // doCopy_MtrlSite /** * Handle the request for Save * * @param data * @throws ImportException */ public void doSaveMtrlSite(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); String siteId = (String) state.getAttribute(STATE_SITE_INSTANCE_ID); List fnlList = (List) state.getAttribute(FINAL_ZIP_IMPORT_SITES); List directList = (List) state.getAttribute(DIRECT_ZIP_IMPORT_SITES); ImportDataSource importDataSource = (ImportDataSource) state.getAttribute(IMPORT_DATA_SOURCE); // combine the selected import items with the mandatory import items fnlList.addAll(directList); Log.info("chef", "doSaveMtrlSite() about to import " + fnlList.size() + " top level items"); Log.info("chef", "doSaveMtrlSite() the importDataSource is " + importDataSource.getClass().getName()); if (importDataSource instanceof SakaiArchive) { Log.info("chef", "doSaveMtrlSite() our data source is a Sakai format"); ((SakaiArchive) importDataSource).buildSourceFolder(fnlList); Log.info("chef", "doSaveMtrlSite() source folder is " + ((SakaiArchive) importDataSource).getSourceFolder()); ArchiveService.merge(((SakaiArchive) importDataSource).getSourceFolder(), siteId, null); } else { importService.doImportItems(importDataSource.getItemsForCategories(fnlList), siteId); } // remove attributes state.removeAttribute(ALL_ZIP_IMPORT_SITES); state.removeAttribute(DIRECT_ZIP_IMPORT_SITES); state.removeAttribute(CLASSIC_ZIP_FILE_NAME); state.removeAttribute(SESSION_CONTEXT_ID); state.removeAttribute(IMPORT_DATA_SOURCE); state.setAttribute(STATE_TEMPLATE_INDEX, "48"); } // doSave_MtrlSite public void doSaveMtrlSiteMsg(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); // remove attributes state.removeAttribute(ALL_ZIP_IMPORT_SITES); state.removeAttribute(FINAL_ZIP_IMPORT_SITES); state.removeAttribute(DIRECT_ZIP_IMPORT_SITES); state.removeAttribute(CLASSIC_ZIP_FILE_NAME); state.removeAttribute(SESSION_CONTEXT_ID); state.setAttribute(STATE_TEMPLATE_INDEX, "12"); } // htripath-end /** * Handle the site search request. */ public void doSite_search(RunData data, Context context) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); // read the search form field into the state object String search = StringUtils.trimToNull(data.getParameters().getString(FORM_SEARCH)); // set the flag to go to the prev page on the next list if (search == null) { state.removeAttribute(STATE_SEARCH); } else { state.setAttribute(STATE_SEARCH, search); } } // doSite_search /** * Handle a Search Clear request. */ public void doSite_search_clear(RunData data, Context context) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); // clear the search state.removeAttribute(STATE_SEARCH); } // doSite_search_clear /** * * @param state * @param context * @param site * @return true if there is any roster attached, false otherwise */ private boolean coursesIntoContext(SessionState state, Context context, Site site) { boolean rv = false; List providerCourseList = SiteParticipantHelper .getProviderCourseList((String) state.getAttribute(STATE_SITE_INSTANCE_ID)); if (providerCourseList != null && providerCourseList.size() > 0) { rv = true; state.setAttribute(SITE_PROVIDER_COURSE_LIST, providerCourseList); Hashtable<String, String> sectionTitles = new Hashtable<String, String>(); for (int i = 0; i < providerCourseList.size(); i++) { String sectionId = (String) providerCourseList.get(i); try { Section s = cms.getSection(sectionId); if (s != null) { sectionTitles.put(sectionId, s.getTitle()); } } catch (IdNotFoundException e) { sectionTitles.put(sectionId, sectionId); M_log.warn("coursesIntoContext: Cannot find section " + sectionId); } } context.put("providerCourseTitles", sectionTitles); context.put("providerCourseList", providerCourseList); } // put manual requested courses into context boolean rv2 = courseListFromStringIntoContext(state, context, site, STATE_CM_REQUESTED_SECTIONS, STATE_CM_REQUESTED_SECTIONS, "cmRequestedCourseList"); // put manual requested courses into context boolean rv3 = courseListFromStringIntoContext(state, context, site, PROP_SITE_REQUEST_COURSE, SITE_MANUAL_COURSE_LIST, "manualCourseList"); return (rv || rv2 || rv3); } /** * * @param state * @param context * @param site * @param site_prop_name * @param state_attribute_string * @param context_string * @return true if there is any roster attached; false otherwise */ private boolean courseListFromStringIntoContext(SessionState state, Context context, Site site, String site_prop_name, String state_attribute_string, String context_string) { boolean rv = false; String courseListString = StringUtils .trimToNull(site != null ? site.getProperties().getProperty(site_prop_name) : null); if (courseListString != null) { rv = true; List courseList = new Vector(); if (courseListString.indexOf("+") != -1) { courseList = new ArrayList(Arrays.asList(groupProvider.unpackId(courseListString))); } else { courseList.add(courseListString); } if (state_attribute_string.equals(STATE_CM_REQUESTED_SECTIONS)) { // need to construct the list of SectionObjects List<SectionObject> soList = new Vector(); for (int i = 0; i < courseList.size(); i++) { String courseEid = (String) courseList.get(i); try { Section s = cms.getSection(courseEid); if (s != null) { soList.add(new SectionObject(s)); } } catch (IdNotFoundException e) { M_log.warn("courseListFromStringIntoContext: cannot find section " + courseEid); } } if (soList.size() > 0) state.setAttribute(STATE_CM_REQUESTED_SECTIONS, soList); } else { // the list is of String objects state.setAttribute(state_attribute_string, courseList); } } context.put(context_string, state.getAttribute(state_attribute_string)); return rv; } /** * buildInstructorSectionsList Build the CourseListItem list for this * Instructor for the requested Term * */ private void buildInstructorSectionsList(SessionState state, ParameterParser params, Context context) { // Site information // The sections of the specified term having this person as Instructor context.put("providerCourseSectionList", state.getAttribute("providerCourseSectionList")); context.put("manualCourseSectionList", state.getAttribute("manualCourseSectionList")); context.put("term", (AcademicSession) state.getAttribute(STATE_TERM_SELECTED)); // bjones86 - SAK-23256 setTermListForContext(context, state, true, false); //-> future terms only context.put(STATE_TERM_COURSE_LIST, state.getAttribute(STATE_TERM_COURSE_LIST)); context.put("tlang", rb); } // buildInstructorSectionsList /** * {@inheritDoc} */ protected int sizeResources(SessionState state) { int size = 0; String search = ""; String userId = SessionManager.getCurrentSessionUserId(); String term = (String) state.getAttribute(STATE_TERM_VIEW_SELECTED); Map<String, String> termProp = null; if (term != null && !"".equals(term) && !TERM_OPTION_ALL.equals(term)) { termProp = new HashMap<String, String>(); termProp.put(Site.PROP_SITE_TERM, term); } // if called from the site list page if (((String) state.getAttribute(STATE_TEMPLATE_INDEX)).equals("0")) { search = StringUtils.trimToNull((String) state.getAttribute(STATE_SEARCH)); if (SecurityService.isSuperUser()) { // admin-type of user String view = (String) state.getAttribute(STATE_VIEW_SELECTED); if (view != null) { if (view.equals(SiteConstants.SITE_TYPE_ALL)) { // search for non-user sites, using // the criteria size = SiteService.countSites(org.sakaiproject.site.api.SiteService.SelectionType.NON_USER, null, search, termProp); } else if (view.equals(SiteConstants.SITE_TYPE_MYWORKSPACE)) { // search for a specific user site // for the particular user id in the // criteria - exact match only try { SiteService.getSite(SiteService.getUserSiteId(search)); size++; } catch (IdUnusedException e) { } } else if (view.equalsIgnoreCase(SiteConstants.SITE_TYPE_DELETED)) { size = SiteService.countSites( org.sakaiproject.site.api.SiteService.SelectionType.ANY_DELETED, null, search, null); } else { // search for specific type of sites size = SiteService.countSites(org.sakaiproject.site.api.SiteService.SelectionType.NON_USER, view, search, termProp); } } } else { Site userWorkspaceSite = null; try { userWorkspaceSite = SiteService.getSite(SiteService.getUserSiteId(userId)); } catch (IdUnusedException e) { M_log.error(this + "sizeResources, template index = 0: Cannot find user " + SessionManager.getCurrentSessionUserId() + "'s My Workspace site.", e); } String view = (String) state.getAttribute(STATE_VIEW_SELECTED); if (view != null) { org.sakaiproject.site.api.SiteService.SelectionType selectionType; if (ServerConfigurationService.getBoolean("sitesetup.show.unpublished", false)) { selectionType = org.sakaiproject.site.api.SiteService.SelectionType.MEMBER; } else { selectionType = org.sakaiproject.site.api.SiteService.SelectionType.ACCESS; } if (view.equals(SiteConstants.SITE_TYPE_ALL)) { view = null; // add my workspace if any if (userWorkspaceSite != null) { if (search != null) { if (userId.indexOf(search) != -1) { size++; } } else { size++; } } size += SiteService.countSites(selectionType, null, search, termProp); } else if (view.equalsIgnoreCase(SiteConstants.SITE_TYPE_DELETED)) { size += SiteService.countSites(org.sakaiproject.site.api.SiteService.SelectionType.DELETED, null, search, null); } else if (view.equals(SiteConstants.SITE_TYPE_MYWORKSPACE)) { // get the current user MyWorkspace site try { SiteService.getSite(SiteService.getUserSiteId(userId)); size++; } catch (IdUnusedException e) { } } else if (view.equals(SiteConstants.SITE_ACTIVE)) { view = null; size += SiteService.countSites(org.sakaiproject.site.api.SiteService.SelectionType.PUBVIEW, view, search, termProp); } else if (view.equals(SiteConstants.SITE_INACTIVE)) { view = null; size += SiteService.countSites( org.sakaiproject.site.api.SiteService.SelectionType.INACTIVE_ONLY, null, search, termProp); } else { // search for specific type of sites size += SiteService.countSites(selectionType, view, search, termProp); } } } } // for SiteInfo list page else if (state.getAttribute(STATE_TEMPLATE_INDEX).toString().equals("12")) { Collection l = (Collection) state.getAttribute(STATE_PARTICIPANT_LIST); size = (l != null) ? l.size() : 0; } return size; } // sizeResources /** * {@inheritDoc} */ protected List readResourcesPage(SessionState state, int first, int last) { String search = StringUtils.trimToNull((String) state.getAttribute(STATE_SEARCH)); // if called from the site list page if (((String) state.getAttribute(STATE_TEMPLATE_INDEX)).equals("0")) { // get sort type SortType sortType = null; String sortBy = (String) state.getAttribute(SORTED_BY); boolean sortAsc = (Boolean.valueOf((String) state.getAttribute(SORTED_ASC))).booleanValue(); if (sortBy.equals(SortType.TITLE_ASC.toString())) { sortType = sortAsc ? SortType.TITLE_ASC : SortType.TITLE_DESC; } else if (sortBy.equals(SortType.TYPE_ASC.toString())) { sortType = sortAsc ? SortType.TYPE_ASC : SortType.TYPE_DESC; } else if (sortBy.equals(SortType.CREATED_BY_ASC.toString())) { sortType = sortAsc ? SortType.CREATED_BY_ASC : SortType.CREATED_BY_DESC; } else if (sortBy.equals(SortType.CREATED_ON_ASC.toString())) { sortType = sortAsc ? SortType.CREATED_ON_ASC : SortType.CREATED_ON_DESC; } else if (sortBy.equals(SortType.PUBLISHED_ASC.toString())) { sortType = sortAsc ? SortType.PUBLISHED_ASC : SortType.PUBLISHED_DESC; } else if (sortBy.equals(SortType.ID_ASC.toString())) { sortType = sortAsc ? SortType.ID_ASC : SortType.ID_DESC; } else if (sortBy.equals(SortType.SOFTLY_DELETED_ASC.toString())) { sortType = sortAsc ? SortType.SOFTLY_DELETED_ASC : SortType.SOFTLY_DELETED_DESC; } String term = (String) state.getAttribute(STATE_TERM_VIEW_SELECTED); Map<String, String> termProp = null; if (term != null && !"".equals(term) && !TERM_OPTION_ALL.equals(term)) { termProp = new HashMap<String, String>(); termProp.put(Site.PROP_SITE_TERM, term); } if (SecurityService.isSuperUser()) { // admin-type of user String view = (String) state.getAttribute(STATE_VIEW_SELECTED); if (view != null) { if (view.equals(SiteConstants.SITE_TYPE_ALL)) { // search for non-user sites, using the // criteria return SiteService.getSites(org.sakaiproject.site.api.SiteService.SelectionType.NON_USER, null, search, termProp, sortType, new PagingPosition(first, last)); } else if (view.equalsIgnoreCase(SiteConstants.SITE_TYPE_MYWORKSPACE)) { // search for a specific user site for // the particular user id in the // criteria - exact match only List rv = new Vector(); try { Site userSite = SiteService.getSite(SiteService.getUserSiteId(search)); rv.add(userSite); } catch (IdUnusedException e) { } return rv; } else if (view.equalsIgnoreCase(SiteConstants.SITE_TYPE_DELETED)) { return SiteService.getSites(org.sakaiproject.site.api.SiteService.SelectionType.ANY_DELETED, null, search, null, sortType, new PagingPosition(first, last)); } else { // search for a specific site return SiteService.getSites(org.sakaiproject.site.api.SiteService.SelectionType.ANY, view, search, termProp, sortType, new PagingPosition(first, last)); } } } else { List rv = new Vector(); Site userWorkspaceSite = null; String userId = SessionManager.getCurrentSessionUserId(); try { userWorkspaceSite = SiteService.getSite(SiteService.getUserSiteId(userId)); } catch (IdUnusedException e) { M_log.error(this + "readResourcesPage template index = 0 :Cannot find user " + SessionManager.getCurrentSessionUserId() + "'s My Workspace site.", e); } String view = (String) state.getAttribute(STATE_VIEW_SELECTED); if (view != null) { org.sakaiproject.site.api.SiteService.SelectionType selectionType; if (ServerConfigurationService.getBoolean("sitesetup.show.unpublished", false)) { selectionType = org.sakaiproject.site.api.SiteService.SelectionType.MEMBER; } else { selectionType = org.sakaiproject.site.api.SiteService.SelectionType.ACCESS; } if (view.equals(SiteConstants.SITE_TYPE_ALL)) { view = null; // add my workspace if any if (userWorkspaceSite != null) { if (search != null) { if (userId.indexOf(search) != -1) { rv.add(userWorkspaceSite); } } else { rv.add(userWorkspaceSite); } } rv.addAll(SiteService.getSites(selectionType, null, search, termProp, sortType, new PagingPosition(first, last))); } else if (view.equals(SiteConstants.SITE_TYPE_MYWORKSPACE)) { // get the current user MyWorkspace site try { rv.add(SiteService.getSite(SiteService.getUserSiteId(userId))); } catch (IdUnusedException e) { } } else if (view.equalsIgnoreCase(SiteConstants.SITE_TYPE_DELETED)) { return SiteService.getSites(org.sakaiproject.site.api.SiteService.SelectionType.DELETED, null, search, null, sortType, new PagingPosition(first, last)); } else if (view.equals(SiteConstants.SITE_ACTIVE)) { rv.addAll(SiteService.getSites(org.sakaiproject.site.api.SiteService.SelectionType.PUBVIEW, null, search, termProp, sortType, new PagingPosition(first, last))); } else if (view.equals(SiteConstants.SITE_INACTIVE)) { rv.addAll(SiteService.getSites( org.sakaiproject.site.api.SiteService.SelectionType.INACTIVE_ONLY, null, search, termProp, sortType, new PagingPosition(first, last))); } else { rv.addAll(SiteService.getSites(selectionType, view, search, termProp, sortType, new PagingPosition(first, last))); } } return rv; } } // if in Site Info list view else if (state.getAttribute(STATE_TEMPLATE_INDEX).toString().equals("12")) { List participants = (state.getAttribute(STATE_PARTICIPANT_LIST) != null) ? collectionToList((Collection) state.getAttribute(STATE_PARTICIPANT_LIST)) : new Vector(); String sortedBy = (String) state.getAttribute(SORTED_BY); String sortedAsc = (String) state.getAttribute(SORTED_ASC); Iterator sortedParticipants = null; if (sortedBy != null) { sortedParticipants = new SortedIterator(participants.iterator(), new SiteComparator(sortedBy, sortedAsc, comparator_locale)); participants.clear(); while (sortedParticipants.hasNext()) { participants.add(sortedParticipants.next()); } } PagingPosition page = new PagingPosition(first, last); page.validate(participants.size()); participants = participants.subList(page.getFirst() - 1, page.getLast()); return participants; } return null; } // readResourcesPage /** * get the selected tool ids from import sites */ private boolean select_import_tools(ParameterParser params, SessionState state) { // has the user selected any tool for importing? boolean anyToolSelected = false; Hashtable importTools = new Hashtable(); // the tools for current site List<String> currentSiteTools = originalToolIds( (List<String>) state.getAttribute(STATE_TOOL_REGISTRATION_SELECTED_LIST), state); // String //all importable tools. //depnding on the config, either one could be selected, which is valid List<String> allImportableTools = new ArrayList<String>(importTools()); if (isAddMissingToolsOnImportEnabled()) { if (allImportableTools != null) { for (int i = 0; i < allImportableTools.size(); i++) { // just verify a valid tool was chosen String toolId = (String) allImportableTools.get(i); if (params.getStrings(toolId) != null) { importTools.put(toolId, new ArrayList(Arrays.asList(params.getStrings(toolId)))); if (!anyToolSelected) { anyToolSelected = true; } } } } } else { if (currentSiteTools != null) { for (int i = 0; i < currentSiteTools.size(); i++) { // any tools chosen from import sites? String toolId = (String) currentSiteTools.get(i); if (params.getStrings(toolId) != null) { importTools.put(toolId, new ArrayList(Arrays.asList(params.getStrings(toolId)))); if (!anyToolSelected) { anyToolSelected = true; } } } } } M_log.debug("tools to import: " + importTools); state.setAttribute(STATE_IMPORT_SITE_TOOL, importTools); return anyToolSelected; } // select_import_tools /** * Is it from the ENW edit page? * * @return ture if the process went through the ENW page; false, otherwise */ private boolean fromENWModifyView(SessionState state) { boolean fromENW = false; List oTools = (List) state.getAttribute(STATE_TOOL_REGISTRATION_OLD_SELECTED_LIST); List toolList = (List) state.getAttribute(STATE_TOOL_REGISTRATION_SELECTED_LIST); if (toolList != null) { for (int i = 0; i < toolList.size() && !fromENW; i++) { String toolId = (String) toolList.get(i); if ("sakai.mailbox".equals(toolId) || isMultipleInstancesAllowed(findOriginalToolId(state, toolId))) { if (oTools == null) { // if during site creation proces fromENW = true; } else if (!oTools.contains(toolId)) { // if user is adding either EmailArchive tool, News tool or // Web Content tool, go to the Customize page for the tool fromENW = true; } } } } return fromENW; } /** * doNew_site is called when the Site list tool bar New... button is clicked * */ public void doNew_site(RunData data) throws Exception { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); // start clean cleanState(state); if (state.getAttribute(STATE_INITIALIZED) == null) { state.setAttribute(STATE_OVERRIDE_TEMPLATE_INDEX, "1"); } else { List siteTypes = (List) state.getAttribute(STATE_SITE_TYPES); if (siteTypes != null) { state.setAttribute(STATE_TEMPLATE_INDEX, "1"); } } } // doNew_site /** * doMenu_site_delete is called when the Site list tool bar Delete button is * clicked * */ public void doMenu_site_delete(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); ParameterParser params = data.getParameters(); if (params.getStrings("selectedMembers") == null) { addAlert(state, rb.getString("java.nosites")); state.setAttribute(STATE_TEMPLATE_INDEX, "0"); return; } String[] removals = (String[]) params.getStrings("selectedMembers"); state.setAttribute(STATE_SITE_REMOVALS, removals); // present confirm delete template state.setAttribute(STATE_TEMPLATE_INDEX, "8"); } // doMenu_site_delete /** * doMenu_site_hard_delete is called when the Site list tool bar Hard Delete button is * clicked * */ public void doMenu_site_hard_delete(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); state.setAttribute(STATE_HARD_DELETE, Boolean.TRUE.toString()); //piggyback on the normal delete method doMenu_site_delete(data); } // doMenu_site_delete /** * Restore a softly deleted site * */ public void doMenu_site_restore(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); ParameterParser params = data.getParameters(); if (params.getStrings("selectedMembers") == null) { addAlert(state, rb.getString("java.nosites")); state.setAttribute(STATE_TEMPLATE_INDEX, "0"); return; } String[] toRestore = (String[]) params.getStrings("selectedMembers"); for (String siteId : toRestore) { try { Site s = SiteService.getSite(siteId); //check if softly deleted if (!s.isSoftlyDeleted()) { M_log.warn("Tried to restore site that has not been marked for deletion: " + siteId); continue; } //reverse it s.setSoftlyDeleted(false); SiteService.save(s); } catch (IdUnusedException e) { M_log.warn("Error restoring site:" + siteId + ":" + e.getClass() + ":" + e.getMessage()); addAlert(state, rb.getString("softly.deleted.invalidsite")); } catch (PermissionException e) { M_log.warn("Error restoring site:" + siteId + ":" + e.getClass() + ":" + e.getMessage()); addAlert(state, rb.getString("softly.deleted.restore.nopermission")); } } } // doSite_restore public void doSite_delete_confirmed(RunData data) { if (!"POST".equals(data.getRequest().getMethod())) { return; } SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); ParameterParser params = data.getParameters(); if (params.getStrings("selectedMembers") == null) { M_log.warn("SiteAction.doSite_delete_confirmed selectedMembers null"); state.setAttribute(STATE_TEMPLATE_INDEX, "0"); // return to the site list return; } List chosenList = new ArrayList(Arrays.asList(params.getStrings("selectedMembers"))); // Site id's of checked sites boolean hardDelete = false; if (StringUtils.equalsIgnoreCase((String) state.getAttribute(STATE_HARD_DELETE), Boolean.TRUE.toString())) { hardDelete = true; } if (!chosenList.isEmpty()) { for (ListIterator i = chosenList.listIterator(); i.hasNext();) { String id = (String) i.next(); String site_title = NULL_STRING; if (SiteService.allowRemoveSite(id)) { try { Site site = SiteService.getSite(id); site_title = site.getTitle(); if (hardDelete) { //hard delete. call upon all implementing services to hard delete their own content doHardDelete(site.getId()); } //now delete the site SiteService.removeSite(site); M_log.debug("Removed site: " + site.getId()); } catch (IdUnusedException e) { M_log.error(this + ".doSite_delete_confirmed - IdUnusedException " + id, e); addAlert(state, rb.getFormattedMessage("java.couldnt", new Object[] { site_title, id })); } catch (PermissionException e) { M_log.error(this + ".doSite_delete_confirmed - PermissionException, site " + site_title + "(" + id + ").", e); addAlert(state, rb.getFormattedMessage("java.dontperm", new Object[] { site_title })); } } else { M_log.warn(this + ".doSite_delete_confirmed - allowRemoveSite failed for site " + id); addAlert(state, rb.getFormattedMessage("java.dontperm", new Object[] { site_title })); } } } state.setAttribute(STATE_TEMPLATE_INDEX, "0"); // return to the site // list // TODO: hard coding this frame id is fragile, portal dependent, and // needs to be fixed -ggolden // schedulePeerFrameRefresh("sitenav"); scheduleTopRefresh(); } // doSite_delete_confirmed /** * get the Site object based on SessionState attribute values * * @return Site object related to current state; null if no such Site object * could be found */ protected Site getStateSite(SessionState state) { return getStateSite(state, false); } // getStateSite /** * get the Site object based on SessionState attribute values * * @param autoContext - If true, we fall back to a context if it exists * @return Site object related to current state; null if no such Site object * could be found */ protected Site getStateSite(SessionState state, boolean autoContext) { Site site = null; if (state.getAttribute(STATE_SITE_INSTANCE_ID) != null) { try { site = SiteService.getSite((String) state.getAttribute(STATE_SITE_INSTANCE_ID)); } catch (Exception ignore) { } } if (site == null && autoContext) { String siteId = ToolManager.getCurrentPlacement().getContext(); try { site = SiteService.getSite(siteId); state.setAttribute(STATE_SITE_INSTANCE_ID, siteId); } catch (Exception ignore) { } } return site; } // getStateSite /** * do called when "eventSubmit_do" is in the request parameters to c is * called from site list menu entry Revise... to get a locked site as * editable and to go to the correct template to begin DB version of writes * changes to disk at site commit whereas XML version writes at server * shutdown */ public void doGet_site(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); ParameterParser params = data.getParameters(); // check form filled out correctly if (params.getStrings("selectedMembers") == null) { addAlert(state, rb.getString("java.nosites")); state.setAttribute(STATE_TEMPLATE_INDEX, "0"); return; } List chosenList = new ArrayList(Arrays.asList(params.getStrings("selectedMembers"))); // Site id's of checked // sites String siteId = ""; if (!chosenList.isEmpty()) { if (chosenList.size() != 1) { addAlert(state, rb.getString("java.please")); state.setAttribute(STATE_TEMPLATE_INDEX, "0"); return; } siteId = (String) chosenList.get(0); getReviseSite(state, siteId); state.setAttribute(SORTED_BY, SiteConstants.SORTED_BY_PARTICIPANT_NAME); state.setAttribute(SORTED_ASC, Boolean.TRUE.toString()); } // reset the paging info resetPaging(state); if (((String) state.getAttribute(STATE_SITE_MODE)).equalsIgnoreCase(SITE_MODE_SITESETUP)) { state.setAttribute(STATE_PAGESIZE_SITESETUP, state.getAttribute(STATE_PAGESIZE)); } Hashtable h = (Hashtable) state.getAttribute(STATE_PAGESIZE_SITEINFO); if (!h.containsKey(siteId)) { // when first entered Site Info, set the participant list size to // 200 as default state.setAttribute(STATE_PAGESIZE, Integer.valueOf(200)); // update h.put(siteId, Integer.valueOf(200)); state.setAttribute(STATE_PAGESIZE_SITEINFO, h); } else { // restore the page size in site info tool state.setAttribute(STATE_PAGESIZE, h.get(siteId)); } } // doGet_site /** * do called when "eventSubmit_do" is in the request parameters to c */ public void doMenu_site_reuse(RunData data) throws Exception { // called from chef_site-list.vm after a site has been selected from // list // create a new Site object based on selected Site object and put in // state // SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); state.setAttribute(STATE_TEMPLATE_INDEX, "1"); } // doMenu_site_reuse /** * do called when "eventSubmit_do" is in the request parameters to c */ public void doMenu_site_revise(RunData data) throws Exception { // called from chef_site-list.vm after a site has been selected from // list // get site as Site object, check SiteCreationStatus and SiteType of // site, put in state, and set STATE_TEMPLATE_INDEX correctly // set mode to state_mode_site_type SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); state.setAttribute(STATE_TEMPLATE_INDEX, "1"); } // doMenu_site_revise /** * doView_sites is called when "eventSubmit_doView_sites" is in the request * parameters */ public void doView_sites(RunData data) throws Exception { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); ParameterParser params = data.getParameters(); state.setAttribute(STATE_VIEW_SELECTED, params.getString("view")); state.setAttribute(STATE_TERM_VIEW_SELECTED, params.getString("termview")); state.setAttribute(STATE_TEMPLATE_INDEX, "0"); resetPaging(state); } // doView_sites /** * do called when "eventSubmit_do" is in the request parameters to c */ public void doView(RunData data) throws Exception { // called from chef_site-list.vm with a select option to build query of // sites // // SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); state.setAttribute(STATE_TEMPLATE_INDEX, "1"); } // doView /** * do called when "eventSubmit_do" is in the request parameters to c */ public void doSite_type(RunData data) { /* * for measuring how long it takes to load sections java.util.Date date = * new java.util.Date(); M_log.debug("***1. start preparing * section:"+date); */ SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); ParameterParser params = data.getParameters(); int index = Integer.valueOf(params.getString("templateIndex")).intValue(); actionForTemplate("continue", index, params, state, data); List<String> pSiteTypes = siteTypeProvider.getTypesForSiteCreation(); String type = StringUtils.trimToNull(params.getString("itemType")); if (type == null) { addAlert(state, rb.getString("java.select") + " "); } else { state.setAttribute(STATE_TYPE_SELECTED, type); setNewSiteType(state, type); if (SiteTypeUtil.isCourseSite(type)) { // UMICH-1035 // redirect redirectCourseCreation(params, state, "selectTerm"); } else if (SiteTypeUtil.isProjectSite(type)) { // UMICH-1035 state.setAttribute(STATE_TEMPLATE_INDEX, "13"); } else if (pSiteTypes != null && pSiteTypes.contains(SiteTypeUtil.getTargetSiteType(type))) { // UMICH-1035 // if of customized type site use pre-defined site info and exclude // from public listing SiteInfo siteInfo = new SiteInfo(); if (state.getAttribute(STATE_SITE_INFO) != null) { siteInfo = (SiteInfo) state.getAttribute(STATE_SITE_INFO); } User currentUser = UserDirectoryService.getCurrentUser(); List<String> idList = new ArrayList<String>(); idList.add(currentUser.getEid()); List<String> nameList = new ArrayList<String>(); nameList.add(currentUser.getDisplayName()); siteInfo.title = siteTypeProvider.getSiteTitle(type, idList); siteInfo.description = siteTypeProvider.getSiteDescription(type, nameList); siteInfo.short_description = siteTypeProvider.getSiteShortDescription(type, idList); siteInfo.include = false; state.setAttribute(STATE_SITE_INFO, siteInfo); // skip directly to confirm creation of site state.setAttribute(STATE_TEMPLATE_INDEX, "42"); } else { state.setAttribute(STATE_TEMPLATE_INDEX, "13"); } // get the user selected template getSelectedTemplate(state, params, type); } redirectToQuestionVM(state, type); } // doSite_type /** * see whether user selected any template * @param state * @param params * @param type */ private void getSelectedTemplate(SessionState state, ParameterParser params, String type) { String templateSiteId = params.getString("selectTemplate" + type); if (templateSiteId != null) { Site templateSite = null; try { templateSite = SiteService.getSite(templateSiteId); // save the template site in state state.setAttribute(STATE_TEMPLATE_SITE, templateSite); // the new site type is based on the template site setNewSiteType(state, templateSite.getType()); } catch (Exception e) { // should never happened, as the list of templates are generated // from existing sites M_log.error(this + ".doSite_type" + e.getClass().getName(), e); state.removeAttribute(STATE_TEMPLATE_SITE); } // grab site info from template SiteInfo siteInfo = new SiteInfo(); if (state.getAttribute(STATE_SITE_INFO) != null) { siteInfo = (SiteInfo) state.getAttribute(STATE_SITE_INFO); } // copy information from template site siteInfo.description = templateSite.getDescription(); siteInfo.short_description = templateSite.getShortDescription(); siteInfo.iconUrl = templateSite.getIconUrl(); siteInfo.infoUrl = templateSite.getInfoUrl(); siteInfo.joinable = templateSite.isJoinable(); siteInfo.joinerRole = templateSite.getJoinerRole(); //siteInfo.include = false; // bjones86 - SAK-24423 - update site info for joinable site settings JoinableSiteSettings.updateSiteInfoFromSitePropertiesOnSelectTemplate(templateSite.getProperties(), siteInfo); List<String> toolIdsSelected = new Vector<String>(); List pageList = templateSite.getPages(); if (!((pageList == null) || (pageList.size() == 0))) { for (ListIterator i = pageList.listIterator(); i.hasNext();) { SitePage page = (SitePage) i.next(); List pageToolList = page.getTools(); if (pageToolList != null && pageToolList.size() > 0) { Tool tConfig = ((ToolConfiguration) pageToolList.get(0)).getTool(); if (tConfig != null) { toolIdsSelected.add(tConfig.getId()); } } } } state.setAttribute(STATE_TOOL_REGISTRATION_SELECTED_LIST, toolIdsSelected); state.setAttribute(STATE_SITE_INFO, siteInfo); } else { // no template selected state.removeAttribute(STATE_TEMPLATE_SITE); } } /** * Depend on the setup question setting, redirect the site setup flow * @param state * @param type */ private void redirectToQuestionVM(SessionState state, String type) { // SAK-12912: check whether there is any setup question defined SiteTypeQuestions siteTypeQuestions = questionService.getSiteTypeQuestions(type); if (siteTypeQuestions != null) { List questionList = siteTypeQuestions.getQuestions(); if (questionList != null && !questionList.isEmpty()) { // there is at least one question defined for this type if (state.getAttribute(STATE_MESSAGE) == null) { state.setAttribute(STATE_SITE_SETUP_QUESTION_NEXT_TEMPLATE, state.getAttribute(STATE_TEMPLATE_INDEX)); state.setAttribute(STATE_TEMPLATE_INDEX, "54"); } } } } /** * Determine whether the selected term is considered of "future term" * @param state * @param t */ private void isFutureTermSelected(SessionState state) { AcademicSession t = (AcademicSession) state.getAttribute(STATE_TERM_SELECTED); int weeks = 0; Calendar c = (Calendar) Calendar.getInstance().clone(); try { weeks = Integer.parseInt( ServerConfigurationService.getString("roster.available.weeks.before.term.start", "0")); c.add(Calendar.DATE, weeks * 7); } catch (Exception ignore) { } if (t != null && t.getStartDate() != null && c.getTimeInMillis() < t.getStartDate().getTime()) { // if a future term is selected state.setAttribute(STATE_FUTURE_TERM_SELECTED, Boolean.TRUE); } else { state.setAttribute(STATE_FUTURE_TERM_SELECTED, Boolean.FALSE); } } public void doChange_user(RunData data) { doSite_type(data); } // doChange_user /** * */ private void removeSection(SessionState state, ParameterParser params) { // v2.4 - added by daisyf // RemoveSection - remove any selected course from a list of // provider courses // check if any section need to be removed removeAnyFlagedSection(state, params); List providerChosenList = (List) state.getAttribute(STATE_ADD_CLASS_PROVIDER_CHOSEN); collectNewSiteInfo(state, params, providerChosenList); } /** * dispatch to different functions based on the option value in the * parameter */ public void doManual_add_course(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); ParameterParser params = data.getParameters(); String option = params.getString("option"); if (option.equalsIgnoreCase("change") || option.equalsIgnoreCase("add")) { readCourseSectionInfo(state, params); String uniqname = StringUtils.trimToNull(params.getString("uniqname")); state.setAttribute(STATE_SITE_QUEST_UNIQNAME, uniqname); // update site information SiteInfo siteInfo = state.getAttribute(STATE_SITE_INFO) != null ? (SiteInfo) state.getAttribute(STATE_SITE_INFO) : new SiteInfo(); if (params.getString("additional") != null) { siteInfo.additional = params.getString("additional"); } state.setAttribute(STATE_SITE_INFO, siteInfo); if (option.equalsIgnoreCase("add")) { if (state.getAttribute(STATE_FUTURE_TERM_SELECTED) != null && !((Boolean) state.getAttribute(STATE_FUTURE_TERM_SELECTED)).booleanValue()) { // if a future term is selected, do not check authorization // uniqname if (uniqname == null) { addAlert(state, rb.getFormattedMessage("java.author", new Object[] { ServerConfigurationService.getString("officialAccountName") })); } else { // in case of multiple instructors List instructors = new ArrayList(Arrays.asList(uniqname.split(","))); for (Iterator iInstructors = instructors.iterator(); iInstructors.hasNext();) { String eid = StringUtils.trimToEmpty((String) iInstructors.next()); try { UserDirectoryService.getUserByEid(eid); } catch (UserNotDefinedException e) { addAlert(state, rb.getFormattedMessage("java.validAuthor", new Object[] { ServerConfigurationService.getString("officialAccountName") })); M_log.error(this + ".doManual_add_course: cannot find user with eid=" + eid, e); } } } } if (state.getAttribute(STATE_MESSAGE) == null) { if (state.getAttribute(STATE_TEMPLATE_SITE) != null) { // create site based on template doFinish(data); } else { if (getStateSite(state) == null) { state.setAttribute(STATE_TEMPLATE_INDEX, "13"); } else { state.setAttribute(STATE_TEMPLATE_INDEX, "44"); } } } } } else if (option.equalsIgnoreCase("back")) { doBack(data); } else if (option.equalsIgnoreCase("cancel")) { if (getStateSite(state) == null) { doCancel_create(data); } else { doCancel(data); } } else if (option.equalsIgnoreCase("removeSection")) { // remove selected section removeAnyFlagedSection(state, params); } } // doManual_add_course /** * dispatch to different functions based on the option value in the * parameter */ public void doSite_information(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); ParameterParser params = data.getParameters(); String option = params.getString("option"); if (option.equalsIgnoreCase("continue")) { doContinue(data); // if create based on template, skip the feature selection Site templateSite = (Site) state.getAttribute(STATE_TEMPLATE_SITE); if (templateSite != null) { state.setAttribute(STATE_TEMPLATE_INDEX, "18"); } } else if (option.equalsIgnoreCase("back")) { doBack(data); } else if (option.equalsIgnoreCase("cancel")) { if (getStateSite(state) == null) { doCancel_create(data); } else { doCancel(data); } } else if (option.equalsIgnoreCase("removeSection")) { // remove selected section removeSection(state, params); } } // doSite_information /** * read the input information of subject, course and section in the manual * site creation page */ private void readCourseSectionInfo(SessionState state, ParameterParser params) { String option = params.getString("option"); int oldNumber = 1; if (state.getAttribute(STATE_MANUAL_ADD_COURSE_NUMBER) != null) { oldNumber = ((Integer) state.getAttribute(STATE_MANUAL_ADD_COURSE_NUMBER)).intValue(); } // read the user input int validInputSites = 0; boolean validInput = true; List multiCourseInputs = new Vector(); for (int i = 0; i < oldNumber; i++) { List requiredFields = sectionFieldProvider.getRequiredFields(); List aCourseInputs = new Vector(); int emptyInputNum = 0; // iterate through all required fields for (int k = 0; k < requiredFields.size(); k++) { SectionField sectionField = (SectionField) requiredFields.get(k); String fieldLabel = sectionField.getLabelKey(); String fieldInput = StringUtils.trimToEmpty(params.getString(fieldLabel + i)); sectionField.setValue(fieldInput); aCourseInputs.add(sectionField); if (fieldInput.length() == 0) { // is this an empty String input? emptyInputNum++; } } // is any input invalid? if (emptyInputNum == 0) { // valid if all the inputs are not empty multiCourseInputs.add(validInputSites++, aCourseInputs); } else if (emptyInputNum == requiredFields.size()) { // ignore if all inputs are empty if (option.equalsIgnoreCase("change")) { multiCourseInputs.add(validInputSites++, aCourseInputs); } } else { // input invalid validInput = false; } } // how many more course/section to include in the site? if (option.equalsIgnoreCase("change")) { if (params.getString("number") != null) { int newNumber = Integer.parseInt(params.getString("number")); state.setAttribute(STATE_MANUAL_ADD_COURSE_NUMBER, Integer.valueOf(oldNumber + newNumber)); List requiredFields = sectionFieldProvider.getRequiredFields(); for (int j = 0; j < newNumber; j++) { // add a new course input List aCourseInputs = new Vector(); // iterate through all required fields for (int m = 0; m < requiredFields.size(); m++) { aCourseInputs = sectionFieldProvider.getRequiredFields(); } multiCourseInputs.add(aCourseInputs); } } } state.setAttribute(STATE_MANUAL_ADD_COURSE_FIELDS, multiCourseInputs); if (!option.equalsIgnoreCase("change")) { if (!validInput || validInputSites == 0) { // not valid input addAlert(state, rb.getString("java.miss")); } // valid input, adjust the add course number state.setAttribute(STATE_MANUAL_ADD_COURSE_NUMBER, Integer.valueOf(validInputSites > 1 ? validInputSites : 1)); } // set state attributes state.setAttribute(FORM_ADDITIONAL, StringUtils.trimToEmpty(params.getString("additional"))); SiteInfo siteInfo = new SiteInfo(); if (state.getAttribute(STATE_SITE_INFO) != null) { siteInfo = (SiteInfo) state.getAttribute(STATE_SITE_INFO); } if (siteInfo.title == null || siteInfo.title.length() == 0) { // if SiteInfo doesn't have title, construct the title List providerCourseList = (List) state.getAttribute(STATE_ADD_CLASS_PROVIDER_CHOSEN); AcademicSession t = (AcademicSession) state.getAttribute(STATE_TERM_SELECTED); if ((providerCourseList == null || providerCourseList.size() == 0) && multiCourseInputs.size() > 0) { String sectionEid = sectionFieldProvider.getSectionEid(t.getEid(), (List) multiCourseInputs.get(0)); // default title String title = sectionFieldProvider.getSectionTitle(t.getEid(), (List) multiCourseInputs.get(0)); try { Section s = cms.getSection(sectionEid); title = s != null ? s.getTitle() : title; } catch (IdNotFoundException e) { M_log.warn("readCourseSectionInfo: Cannot find section " + sectionEid); } siteInfo.title = title; state.setAttribute(STATE_SITE_INFO, siteInfo); } } } // readCourseSectionInfo /** * * @param state * @param type */ private void setNewSiteType(SessionState state, String type) { state.setAttribute(STATE_SITE_TYPE, type); // start out with fresh site information SiteInfo siteInfo = new SiteInfo(); siteInfo.site_type = type; siteInfo.published = true; User u = UserDirectoryService.getCurrentUser(); if (u != null) { siteInfo.site_contact_name = u.getDisplayName(); siteInfo.site_contact_email = u.getEmail(); } state.setAttribute(STATE_SITE_INFO, siteInfo); // set tool registration list if (!"copy".equals(type)) { setToolRegistrationList(state, type); } } /** SAK16600 insert current site type into context * @param context current context * @param type current type * @return courseSiteType type of 'course' */ private void setTypeIntoContext(Context context, String type) { if (type != null && SiteTypeUtil.isCourseSite(type)) { context.put("isCourseSite", Boolean.TRUE); context.put("isProjectSite", Boolean.FALSE); } else { context.put("isCourseSite", Boolean.FALSE); if (type != null && SiteTypeUtil.isProjectSite(type)) { context.put("isProjectSite", Boolean.TRUE); } } } /** * Set the state variables for tool registration list basd on current site type, save to STATE_TOOL_GROUP_LIST. This list should include * all tool types - normal, home, multiples and blti. Note that if the toolOrder.xml is in the original format, this list will consist of * all tools in a single group * @param state * @param is type * @param site */ private Map<String, List> getTools(SessionState state, String type, Site site) { boolean checkhome = state.getAttribute(STATE_TOOL_HOME_SELECTED) != null ? ((Boolean) state.getAttribute(STATE_TOOL_HOME_SELECTED)).booleanValue() : true; boolean isNewToolOrderType = ServerConfigurationService.getBoolean("config.sitemanage.useToolGroup", false); Map<String, List> toolGroup = new LinkedHashMap<String, List>(); MyTool newTool = null; File moreInfoDir = new File(moreInfoPath); List toolList; // if this is legacy format toolOrder.xml file, get all tools by siteType if (isNewToolOrderType == false) { String defaultGroupName = rb.getString("tool.group.default"); toolGroup.put(defaultGroupName, getOrderedToolList(state, defaultGroupName, type, checkhome)); } else { // get all the groups that are available for this site type List groups = ServerConfigurationService.getCategoryGroups(SiteTypeUtil.getTargetSiteType(type)); for (Iterator<String> itr = groups.iterator(); itr.hasNext();) { String groupId = itr.next(); String groupName = getGroupName(groupId); toolList = getGroupedToolList(groupId, groupName, type, checkhome, moreInfoDir); if (toolList.size() > 0) { toolGroup.put(groupName, toolList); } } // add ungroups tools to end of toolGroup list String ungroupedName = getGroupName(UNGROUPED_TOOL_TITLE); List ungroupedList = getUngroupedTools(ungroupedName, toolGroup, state, moreInfoDir, site); if (ungroupedList.size() > 0) { toolGroup.put(ungroupedName, ungroupedList); } } // add external tools to end of toolGroup list String externaltoolgroupname = getGroupName(LTI_TOOL_TITLE); List externalTools = getLtiToolGroup(externaltoolgroupname, moreInfoDir, site); if (externalTools.size() > 0) toolGroup.put(externaltoolgroupname, externalTools); // Home page should be auto-selected if (checkhome == true) { state.setAttribute(STATE_TOOL_HOME_SELECTED, new Boolean(true)); } // refresh selectedList List<String> selectedTools = new ArrayList<String>(); for (Iterator itr = toolGroup.keySet().iterator(); itr.hasNext();) { String key = (String) itr.next(); List toolGroupSelectedList = (List) toolGroup.get(key); for (Iterator listItr = toolGroupSelectedList.iterator(); listItr.hasNext();) { MyTool tool = (MyTool) listItr.next(); if (tool.selected) { selectedTools.add(tool.id); } } } List toolRegistrationSelectedList = (List) state.getAttribute(STATE_TOOL_REGISTRATION_SELECTED_LIST); //If this is the first time through add these selected tools as the default otherwise don't touch this if (toolRegistrationSelectedList == null) { state.setAttribute(STATE_TOOL_REGISTRATION_SELECTED_LIST, selectedTools); } return toolGroup; } /** * Get ordered, ungrouped list of tools * @param groupName - name of default group to add all tools * @param type - site type * @param checkhome */ private List getOrderedToolList(SessionState state, String groupName, String type, boolean checkhome) { MyTool newTool = null; List toolsInOrderedList = new ArrayList(); // see setToolRegistrationList() List toolList = (List) state.getAttribute(STATE_TOOL_REGISTRATION_LIST); // mark the required tools List requiredTools = ServerConfigurationService.getToolsRequired(SiteTypeUtil.getTargetSiteType(type)); // mark the default tools List defaultTools = ServerConfigurationService.getDefaultTools(SiteTypeUtil.getTargetSiteType(type)); // add Home tool only once boolean hasHomeTool = false; for (Iterator itr = toolList.iterator(); itr.hasNext();) { MyTool tr = (MyTool) itr.next(); String toolId = tr.getId(); if (TOOL_ID_HOME.equals(tr.getId())) { hasHomeTool = true; } if (tr != null) { newTool = new MyTool(); newTool.title = tr.getTitle(); newTool.id = toolId; newTool.description = tr.getDescription(); newTool.group = groupName; // does tool allow multiples and if so are they already defined? newTool.multiple = isMultipleInstancesAllowed(toolId); // SAK-16600 - this flag will allow action for template#3 to massage list into new format if (requiredTools != null && requiredTools.contains(toolId)) { newTool.required = true; } if (defaultTools != null && defaultTools.contains(toolId)) { newTool.selected = true; } toolsInOrderedList.add(newTool); } } if (!hasHomeTool) { // add Home tool to the front of the tool list newTool = new MyTool(); newTool.id = TOOL_ID_HOME; newTool.selected = checkhome; newTool.required = false; newTool.multiple = false; toolsInOrderedList.add(0, newTool); } return toolsInOrderedList; } // SAK-23811 private List getGroupedToolList(String groupId, String groupName, String type, boolean checkhome, File moreInfoDir) { List toolsInGroup = new ArrayList(); MyTool newTool = null; List toolList = ServerConfigurationService.getToolGroup(groupId); // empty list if (toolList != null) { for (Iterator<String> iter = toolList.iterator(); iter.hasNext();) { String id = iter.next(); String relativeWebPath = null; if (id.equals(TOOL_ID_HOME)) { // SAK-23208 newTool = new MyTool(); newTool.id = id; newTool.title = rb.getString("java.home"); newTool.description = rb.getString("java.home"); newTool.selected = checkhome; newTool.required = ServerConfigurationService.toolGroupIsRequired(groupId, TOOL_ID_HOME); newTool.multiple = false; } else { Tool tr = ToolManager.getTool(id); if (tr != null) { String toolId = tr.getId(); if (isSiteTypeInToolCategory(SiteTypeUtil.getTargetSiteType(type), tr) && notStealthOrHiddenTool(toolId)) // SAK 23808 { newTool = new MyTool(); newTool.title = tr.getTitle(); newTool.id = toolId; newTool.description = tr.getDescription(); newTool.group = groupName; newTool.moreInfo = getMoreInfoUrl(moreInfoDir, toolId); newTool.required = ServerConfigurationService.toolGroupIsRequired(groupId, toolId); newTool.selected = ServerConfigurationService.toolGroupIsSelected(groupId, toolId); // does tool allow multiples and if so are they already defined? newTool.multiple = isMultipleInstancesAllowed(toolId); // SAK-16600 - this flag will allow action for template#3 to massage list into new format } } } if (newTool != null) { toolsInGroup.add(newTool); newTool = null; } } } M_log.debug(groupName + ": loaded " + new Integer(toolsInGroup.size()).toString() + " tools"); return toolsInGroup; } /* * Given groupId, return localized name from tools.properties */ private String getGroupName(String groupId) { // undefined group will return standard '[missing key]' error string return ToolManager.getLocalizedToolProperty(groupId, "title"); } /* * Using moreInfoDir, if toolId is found in the dir return path otherwise return null */ private String getMoreInfoImg(File infoDir, String toolId) { String moreInfoUrl = null; try { Collection<File> files = FileUtils.listFiles(infoDir, new WildcardFileFilter(toolId + "*"), null); if (files.isEmpty() == false) { File mFile = files.iterator().next(); moreInfoUrl = libraryPath + mFile.getName(); // toolId; } } catch (Exception e) { M_log.info("unable to read moreinfo: " + e.getMessage()); } return moreInfoUrl; } /* * Using moreInfoDir, if toolId is found in the dir return path otherwise return null */ private String getMoreInfoUrl(File infoDir, String toolId) { String moreInfoUrl = null; try { Collection<File> files = FileUtils.listFiles(infoDir, new WildcardFileFilter(toolId + "*"), null); if (files.isEmpty() == false) { for (File mFile : files) { String name = mFile.getName(); int lastIndexOf = name.lastIndexOf('.'); String fNameWithOutExtension = name.substring(0, lastIndexOf); if (fNameWithOutExtension.equals(toolId)) { moreInfoUrl = libraryPath + mFile.getName(); break; } } } } catch (Exception e) { M_log.info("unable to read moreinfo" + e.getMessage()); } return moreInfoUrl; } /* SAK-16600 given list, return only those tools tha are BLTI * NOTE - this method is not yet used * @param selToolList list where tool.selected = true * @return list of tools that are selected and blti */ private List<String> getToolGroupLtiTools(List<String> selToolList) { List<String> onlyLtiTools = new ArrayList<String>(); List<Map<String, Object>> allTools = m_ltiService.getTools(null, null, 0, 0); if (allTools != null && !allTools.isEmpty()) { for (Map<String, Object> tool : allTools) { Set keySet = tool.keySet(); Integer ltiId = (Integer) tool.get("id"); if (ltiId != null) { String toolId = ltiId.toString(); if (selToolList.contains(toolId)) { onlyLtiTools.add(toolId); } } } } return onlyLtiTools; } /* SAK-16600 return selected list with blti tools removed * NOTE this method is not yet used * @param selToolList list where tool.selected = true * @return list of tools that are selected and not blti */ private List<String> removeLtiTools(List<String> selToolList) { List<String> noLtiList = new ArrayList<String>(); noLtiList.addAll(selToolList); List<String> ltiList = new ArrayList<String>(); List<Map<String, Object>> allTools = m_ltiService.getTools(null, null, 0, 0); if (allTools != null && !allTools.isEmpty()) { for (Map<String, Object> tool : allTools) { Set keySet = tool.keySet(); Integer ltiId = (Integer) tool.get("id"); if (ltiId != null) { String toolId = ltiId.toString(); if (!ltiList.contains(toolId)) { ltiList.add(toolId); } } } } boolean result = noLtiList.removeAll(ltiList); return noLtiList; } private List selectedLTITools(Site site) { List selectedLTI = new ArrayList(); if (site != null) { String siteId = site.getId(); List<Map<String, Object>> contents = m_ltiService.getContents(null, null, 0, 0); HashMap<String, Map<String, Object>> linkedLtiContents = new HashMap<String, Map<String, Object>>(); for (Map<String, Object> content : contents) { String ltiToolId = content.get(m_ltiService.LTI_TOOL_ID).toString(); String ltiSiteId = StringUtils.trimToNull((String) content.get(m_ltiService.LTI_SITE_ID)); if ((ltiSiteId != null) && ltiSiteId.equals(siteId)) { selectedLTI.add(ltiToolId); } } } return selectedLTI; } // SAK-16600 find selected flag for ltiTool // MAR25 create list of all selected ltitools private boolean isLtiToolInSite(Long toolId, String siteId) { if (siteId == null) return false; Map<String, Object> toolProps = m_ltiService.getContent(toolId, siteId); // getTool(toolId); if (toolProps == null) { return false; } else { String toolSite = StringUtils.trimToNull((String) toolProps.get(m_ltiService.LTI_SITE_ID)); return siteId.equals(toolSite); } } /* SAK 16600 if toolGroup mode is active; and toolGroups don't use all available tools, put remaining tools into * 'ungrouped' group having name 'GroupName' * @param moreInfoDir file pointer to directory of MoreInfo content * @param site current site * @return list of MyTool items */ private List getUngroupedTools(String ungroupedName, Map<String, List> toolsByGroup, SessionState state, File moreInforDir, Site site) { // Get all tools for site List ungroupedToolsOld = (List) state.getAttribute(STATE_TOOL_REGISTRATION_LIST); // copy the list of tools to avoid ConcurrentModificationException List<MyTool> ungroupedTools = new Vector<MyTool>(); if (ungroupedToolsOld != null) ungroupedTools.addAll(ungroupedToolsOld); // get all the tool groups that are available for this site for (Iterator<String> toolgroupitr = toolsByGroup.keySet().iterator(); toolgroupitr.hasNext();) { String groupName = toolgroupitr.next(); List toolList = toolsByGroup.get(groupName); for (Iterator toollistitr = toolList.iterator(); toollistitr.hasNext();) { MyTool ungroupedTool = (MyTool) toollistitr.next(); if (ungroupedTools.contains(ungroupedTool)) { // remove all tools that are in a toolGroup list ungroupedTools.remove(ungroupedTool); } } } // remove all toolMultiples Map toolMultiples = getToolGroupMultiples(state, ungroupedTools); if (toolMultiples != null) { for (Iterator tmiter = toolMultiples.keySet().iterator(); tmiter.hasNext();) { String toolId = (String) tmiter.next(); List multiToolList = (List) toolMultiples.get(toolId); for (Iterator toollistitr = multiToolList.iterator(); toollistitr.hasNext();) { MyTool multitoolId = (MyTool) toollistitr.next(); if (ungroupedTools.contains(multitoolId)) { ungroupedTools.remove(multitoolId); } } } } // assign group name to all remaining tools for (Iterator listitr = ungroupedTools.iterator(); listitr.hasNext();) { MyTool tool = (MyTool) listitr.next(); tool.group = ungroupedName; } return ungroupedTools; } /* SAK 16600 Create list of ltitools to add to toolgroups; set selected for those // tools already added to a sites with properties read to add to toolsByGroup list * @param groupName name of the current group * @param moreInfoDir file pointer to directory of MoreInfo content * @param site current site * @return list of MyTool items */ private List getLtiToolGroup(String groupName, File moreInfoDir, Site site) { List ltiSelectedTools = selectedLTITools(site); List ltiTools = new ArrayList(); List<Map<String, Object>> allTools; if (site == null) allTools = m_ltiService.getTools(null, null, 0, 0); else allTools = m_ltiService.getToolsDao(null, null, 0, 0, site.getId()); if (allTools != null && !allTools.isEmpty()) { for (Map<String, Object> tool : allTools) { Set keySet = tool.keySet(); String toolIdString = ObjectUtils.toString(tool.get(m_ltiService.LTI_ID)); boolean toolStealthed = "1".equals(ObjectUtils.toString(tool.get(m_ltiService.LTI_VISIBLE))); boolean ltiToolSelected = ltiSelectedTools.contains(toolIdString); try { // in Oracle, the lti tool id is returned as BigDecimal, which cannot be casted into Integer directly Integer ltiId = Integer.valueOf(toolIdString); if (ltiId != null) { String ltiToolId = ltiId.toString(); if (ltiToolId != null && (!toolStealthed || ltiToolSelected)) { String relativeWebPath = null; MyTool newTool = new MyTool(); newTool.title = tool.get("title").toString(); newTool.id = LTITOOL_ID_PREFIX + ltiToolId; newTool.description = (String) tool.get("description"); newTool.group = groupName; relativeWebPath = getMoreInfoUrl(moreInfoDir, ltiToolId); if (relativeWebPath != null) { newTool.moreInfo = relativeWebPath; } // SAK16600 should this be a property or specified in toolOrder.xml? newTool.required = false; newTool.selected = ltiToolSelected; ltiTools.add(newTool); } } } catch (NumberFormatException e) { M_log.error(this + " Cannot cast tool id String " + toolIdString + " into integer value."); } } } return ltiTools; } /** * Set the state variables for tool registration list basd on site type * @param state * @param type */ private void setToolRegistrationList(SessionState state, String type) { state.removeAttribute(STATE_TOOL_REGISTRATION_SELECTED_LIST); state.removeAttribute(STATE_TOOL_REGISTRATION_OLD_SELECTED_LIST); state.removeAttribute(STATE_TOOL_REGISTRATION_OLD_SELECTED_HOME); state.removeAttribute(STATE_MULTIPLE_TOOL_ID_SET); // get the tool id set which allows for multiple instances Set multipleToolIdSet = new HashSet(); HashMap multipleToolConfiguration = new HashMap<String, HashMap<String, String>>(); // get registered tools list Set categories = new HashSet(); categories.add(type); categories.add(SiteTypeUtil.getTargetSiteType(type)); // UMICH-1035 Set toolRegistrations = ToolManager.findTools(categories, null); if ((toolRegistrations == null || toolRegistrations.size() == 0) && state.getAttribute(STATE_DEFAULT_SITE_TYPE) != null) { // use default site type and try getting tools again type = (String) state.getAttribute(STATE_DEFAULT_SITE_TYPE); categories.clear(); categories.add(SiteTypeUtil.getTargetSiteType(type)); //UMICH-1035 toolRegistrations = ToolManager.findTools(categories, null); } List tools = new Vector(); SortedIterator i = new SortedIterator(toolRegistrations.iterator(), new ToolComparator()); for (; i.hasNext();) { // form a new Tool Tool tr = (Tool) i.next(); MyTool newTool = new MyTool(); newTool.title = tr.getTitle(); newTool.id = tr.getId(); newTool.description = tr.getDescription(); String originalToolId = findOriginalToolId(state, tr.getId()); if (isMultipleInstancesAllowed(originalToolId)) { // of a tool which allows multiple instances multipleToolIdSet.add(tr.getId()); // get the configuration for multiple instance HashMap<String, String> toolConfigurations = getMultiToolConfiguration(originalToolId, null); multipleToolConfiguration.put(tr.getId(), toolConfigurations); } tools.add(newTool); } state.setAttribute(STATE_TOOL_REGISTRATION_LIST, tools); state.setAttribute(STATE_MULTIPLE_TOOL_ID_SET, multipleToolIdSet); state.setAttribute(STATE_MULTIPLE_TOOL_CONFIGURATION, multipleToolConfiguration); } /** * Set the field on which to sort the list of students * */ public void doSort_roster(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); // get the field on which to sort the student list ParameterParser params = data.getParameters(); String criterion = params.getString("criterion"); // current sorting sequence String asc = ""; if (!criterion.equals(state.getAttribute(SORTED_BY))) { state.setAttribute(SORTED_BY, criterion); asc = Boolean.TRUE.toString(); state.setAttribute(SORTED_ASC, asc); } else { // current sorting sequence asc = (String) state.getAttribute(SORTED_ASC); // toggle between the ascending and descending sequence if (asc.equals(Boolean.TRUE.toString())) { asc = Boolean.FALSE.toString(); } else { asc = Boolean.TRUE.toString(); } state.setAttribute(SORTED_ASC, asc); } } // doSort_roster /** * Set the field on which to sort the list of sites * */ public void doSort_sites(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); // call this method at the start of a sort for proper paging resetPaging(state); // get the field on which to sort the site list ParameterParser params = data.getParameters(); String criterion = params.getString("criterion"); // current sorting sequence String asc = ""; if (!criterion.equals(state.getAttribute(SORTED_BY))) { state.setAttribute(SORTED_BY, criterion); asc = Boolean.TRUE.toString(); state.setAttribute(SORTED_ASC, asc); } else { // current sorting sequence asc = (String) state.getAttribute(SORTED_ASC); // toggle between the ascending and descending sequence if (asc.equals(Boolean.TRUE.toString())) { asc = Boolean.FALSE.toString(); } else { asc = Boolean.TRUE.toString(); } state.setAttribute(SORTED_ASC, asc); } state.setAttribute(SORTED_BY, criterion); } // doSort_sites /** * doContinue is called when "eventSubmit_doContinue" is in the request * parameters */ public void doContinue(RunData data) { // Put current form data in state and continue to the next template, // make any permanent changes SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); ParameterParser params = data.getParameters(); int index = Integer.valueOf(params.getString("templateIndex")).intValue(); // Let actionForTemplate know to make any permanent changes before // continuing to the next template String direction = "continue"; String option = params.getString("option"); actionForTemplate(direction, index, params, state, data); if (state.getAttribute(STATE_MESSAGE) == null) { if (index == 36 && ("add").equals(option)) { // this is the Add extra Roster(s) case after a site is created state.setAttribute(STATE_TEMPLATE_INDEX, "44"); } else if (params.getString("continue") != null) { state.setAttribute(STATE_TEMPLATE_INDEX, params.getString("continue")); } } }// doContinue /** * handle with continue add new course site options * */ public void doContinue_new_course(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); ParameterParser params = data.getParameters(); String option = data.getParameters().getString("option"); if ("continue".equals(option)) { doContinue(data); } else if ("cancel".equals(option)) { doCancel_create(data); } else if ("back".equals(option)) { doBack(data); } else if ("cancel".equals(option)) { doCancel_create(data); } else if ("norosters".equals(option)) { state.setAttribute(STATE_TEMPLATE_INDEX, "13"); } else if (option.equalsIgnoreCase("change_user")) { // SAK-22915 doChange_user(data); } else if (option.equalsIgnoreCase("change")) { // change term String termId = params.getString("selectTerm"); AcademicSession t = cms.getAcademicSession(termId); state.setAttribute(STATE_TERM_SELECTED, t); isFutureTermSelected(state); } else if (option.equalsIgnoreCase("cancel_edit")) { // cancel doCancel(data); } else if (option.equalsIgnoreCase("add")) { isFutureTermSelected(state); // continue doContinue(data); } } // doContinue_new_course /** * doBack is called when "eventSubmit_doBack" is in the request parameters * Pass parameter to actionForTemplate to request action for backward * direction */ public void doBack(RunData data) { // Put current form data in state and return to the previous template SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); ParameterParser params = data.getParameters(); int currentIndex = Integer.parseInt((String) state.getAttribute(STATE_TEMPLATE_INDEX)); state.setAttribute(STATE_TEMPLATE_INDEX, params.getString("back")); // Let actionForTemplate know not to make any permanent changes before // continuing to the next template String direction = "back"; actionForTemplate(direction, currentIndex, params, state, data); // remove the last template index from the list removeLastIndexInStateVisitedTemplates(state); }// doBack /** * doFinish is called when a site has enough information to be saved as an * unpublished site */ public void doFinish(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); ParameterParser params = data.getParameters(); if (state.getAttribute(STATE_MESSAGE) == null) { state.setAttribute(STATE_TEMPLATE_INDEX, params.getString("continue")); addNewSite(params, state); Site site = getStateSite(state); // SAK-23468 Add new site params to state setNewSiteStateParameters(site, state); // Since the option to input aliases is presented to users prior to // the new site actually being created, it doesn't really make sense // to check permissions on the newly created site when we assign // aliases, hence the advisor here. // // Set site aliases before dealing with tools b/c site aliases // are more general and can, for example, serve the same purpose // as mail channel aliases but the reverse is not true. if (aliasAssignmentForNewSitesEnabled(state)) { SecurityService.pushAdvisor(new SecurityAdvisor() { public SecurityAdvice isAllowed(String userId, String function, String reference) { if (AliasService.SECURE_ADD_ALIAS.equals(function) || AliasService.SECURE_UPDATE_ALIAS.equals(function)) { return SecurityAdvice.ALLOWED; } return SecurityAdvice.PASS; } }); try { setSiteReferenceAliases(state, site.getId()); // sets aliases for the site entity itself } finally { SecurityService.popAdvisor(); } } SiteInfo siteInfo = (SiteInfo) state.getAttribute(STATE_SITE_INFO); if (siteInfo != null) { for (String role : siteInfo.additionalRoles) { updateAdditionalRole(state, site, role, true); } } Site templateSite = (Site) state.getAttribute(STATE_TEMPLATE_SITE); if (templateSite == null) { // normal site creation: add the features. saveFeatures(params, state, site); try { site = SiteService.getSite(site.getId()); } catch (Exception ee) { M_log.error(this + "doFinish: unable to reload site " + site.getId() + " after copying tools"); } } else { // creating based on template if (state.getAttribute(STATE_TEMPLATE_SITE_COPY_CONTENT) != null) { // create based on template: skip add features, and copying all the contents from the tools in template site importToolContent(templateSite.getId(), site, true); try { site = SiteService.getSite(site.getId()); } catch (Exception ee) { M_log.error(this + "doFinish: unable to reload site " + site.getId() + " after importing tools"); } } // copy members if (state.getAttribute(STATE_TEMPLATE_SITE_COPY_USERS) != null) { try { AuthzGroup templateGroup = authzGroupService.getAuthzGroup(templateSite.getReference()); AuthzGroup newGroup = authzGroupService.getAuthzGroup(site.getReference()); for (Iterator mi = templateGroup.getMembers().iterator(); mi.hasNext();) { Member member = (Member) mi.next(); if (newGroup.getMember(member.getUserId()) == null) { // only add those user who is not in the new site yet newGroup.addMember(member.getUserId(), member.getRole().getId(), member.isActive(), member.isProvided()); } } authzGroupService.save(newGroup); } catch (Exception copyUserException) { M_log.warn(this + "doFinish: copy user exception template site =" + templateSite.getReference() + " new site =" + site.getReference() + " " + copyUserException.getMessage()); } } else { // if not bringing user over, remove the provider information try { AuthzGroup newGroup = authzGroupService.getAuthzGroup(site.getReference()); newGroup.setProviderGroupId(null); authzGroupService.save(newGroup); // make sure current user stays in the site newGroup = authzGroupService.getAuthzGroup(site.getReference()); String currentUserId = UserDirectoryService.getCurrentUser().getId(); if (newGroup.getUserRole(currentUserId) == null) { // add advisor SecurityService.pushAdvisor(new SecurityAdvisor() { public SecurityAdvice isAllowed(String userId, String function, String reference) { return SecurityAdvice.ALLOWED; } }); newGroup.addMember(currentUserId, newGroup.getMaintainRole(), true, false); authzGroupService.save(newGroup); // remove advisor SecurityService.popAdvisor(); } } catch (Exception removeProviderException) { M_log.warn(this + "doFinish: remove provider id " + " new site =" + site.getReference() + " " + removeProviderException.getMessage()); } try { site = SiteService.getSite(site.getId()); } catch (Exception ee) { M_log.error(this + "doFinish: unable to reload site " + site.getId() + " after updating roster."); } } // We don't want the new site to automatically be a template site.getPropertiesEdit().removeProperty("template"); // publish the site or not based on the template choice site.setPublished(state.getAttribute(STATE_TEMPLATE_PUBLISH) != null ? true : false); // Update the icons URL. String newSiteIconUrl = transferSiteResource(templateSite.getId(), site.getId(), site.getIconUrl()); site.setIconUrl(newSiteIconUrl); userNotificationProvider.notifyTemplateUse(templateSite, UserDirectoryService.getCurrentUser(), site); } ResourcePropertiesEdit rp = site.getPropertiesEdit(); // for course sites String siteType = site.getType(); if (SiteTypeUtil.isCourseSite(siteType)) { AcademicSession term = null; if (state.getAttribute(STATE_TERM_SELECTED) != null) { term = (AcademicSession) state.getAttribute(STATE_TERM_SELECTED); rp.addProperty(Site.PROP_SITE_TERM, term.getTitle()); rp.addProperty(Site.PROP_SITE_TERM_EID, term.getEid()); } // update the site and related realm based on the rosters chosen or requested updateCourseSiteSections(state, site.getId(), rp, term); } else { // for non course type site, send notification email sendSiteNotification(state, getStateSite(state), null); } // commit site commitSite(site); //merge uploaded archive if required if (state.getAttribute(STATE_CREATE_FROM_ARCHIVE) == Boolean.TRUE) { doMergeArchiveIntoNewSite(site.getId(), state); } if (templateSite == null) { // save user answers saveSiteSetupQuestionUserAnswers(state, site.getId()); } // TODO: hard coding this frame id is fragile, portal dependent, and // needs to be fixed -ggolden // schedulePeerFrameRefresh("sitenav"); scheduleTopRefresh(); resetPaging(state); // clean state variables cleanState(state); if (SITE_MODE_HELPER.equals(state.getAttribute(STATE_SITE_MODE))) { state.setAttribute(SiteHelper.SITE_CREATE_SITE_ID, site.getId()); state.setAttribute(STATE_SITE_MODE, SITE_MODE_HELPER_DONE); } state.setAttribute(STATE_TEMPLATE_INDEX, "0"); } }// doFinish /** * get one alias for site, if it exists * @param reference * @return */ private String getSiteAlias(String reference) { String alias = null; if (reference != null) { // get the email alias when an Email Archive tool has been selected List aliases = aliasService.getAliases(reference, 1, 1); if (aliases.size() > 0) { alias = ((Alias) aliases.get(0)).getId(); } } return alias; } /** * Processes site entity aliases associated with the {@link SiteInfo} * object currently cached in the session. Checked exceptions during * processing of any given alias results in an alert and a log message, * but all aliases will be processed. This behavior is an attempt to be * consistent with established, heads-down style request processing * behaviors, e.g. in {@link #doFinish(RunData)}. * * <p>Processing should work for both site creation and modification.</p> * * <p>Implements no permission checking of its own, so insufficient permissions * will result in an alert being cached in the current session. Thus it * is typically appropriate for the caller to check permissions first, * especially because insufficient permissions may result in a * misleading {@link SiteInfo) state. Specifically, the alias collection * is likely empty, which is consistent with handling of other read-only * fields in that object, but which would cause this method to attempt * to delete all aliases for the current site.</p> * * <p>Exits quietly if no {@link SiteInfo} object has been cached under * the {@link #STATE_SITE_INFO} key.</p> * * @param state * @param siteId */ private void setSiteReferenceAliases(SessionState state, String siteId) { SiteInfo siteInfo = (SiteInfo) state.getAttribute(STATE_SITE_INFO); if (siteInfo == null) { return; } String siteReference = SiteService.siteReference(siteId); List<String> existingAliasIds = toIdList(aliasService.getAliases(siteReference)); Set<String> proposedAliasIds = siteInfo.siteRefAliases; Set<String> aliasIdsToDelete = new HashSet<String>(existingAliasIds); aliasIdsToDelete.removeAll(proposedAliasIds); Set<String> aliasIdsToAdd = new HashSet<String>(proposedAliasIds); aliasIdsToAdd.removeAll(existingAliasIds); for (String aliasId : aliasIdsToDelete) { try { aliasService.removeAlias(aliasId); } catch (PermissionException e) { addAlert(state, rb.getFormattedMessage("java.delalias", new Object[] { aliasId })); M_log.error(this + ".setSiteReferenceAliases: " + rb.getFormattedMessage("java.delalias", new Object[] { aliasId }), e); } catch (IdUnusedException e) { // no problem } catch (InUseException e) { addAlert(state, rb.getFormattedMessage("java.delalias", new Object[] { aliasId }) + rb.getFormattedMessage("java.alias.locked", new Object[] { aliasId })); M_log.error(this + ".setSiteReferenceAliases: " + rb.getFormattedMessage("java.delalias", new Object[] { aliasId }) + rb.getFormattedMessage("java.alias.locked", new Object[] { aliasId }), e); } } for (String aliasId : aliasIdsToAdd) { try { aliasService.setAlias(aliasId, siteReference); } catch (PermissionException e) { addAlert(state, rb.getString("java.addalias") + " "); M_log.error(this + ".setSiteReferenceAliases: " + rb.getString("java.addalias"), e); } catch (IdInvalidException e) { addAlert(state, rb.getFormattedMessage("java.alias.isinval", new Object[] { aliasId })); M_log.error(this + ".setSiteReferenceAliases: " + rb.getFormattedMessage("java.alias.isinval", new Object[] { aliasId }), e); } catch (IdUsedException e) { addAlert(state, rb.getFormattedMessage("java.alias.exists", new Object[] { aliasId })); M_log.error(this + ".setSiteReferenceAliases: " + rb.getFormattedMessage("java.alias.exists", new Object[] { aliasId }), e); } } } /** * save user answers * @param state * @param siteId */ private void saveSiteSetupQuestionUserAnswers(SessionState state, String siteId) { // update the database with user answers to SiteSetup questions if (state.getAttribute(STATE_SITE_SETUP_QUESTION_ANSWER) != null) { Set<SiteSetupUserAnswer> userAnswers = (Set<SiteSetupUserAnswer>) state .getAttribute(STATE_SITE_SETUP_QUESTION_ANSWER); for (Iterator<SiteSetupUserAnswer> aIterator = userAnswers.iterator(); aIterator.hasNext();) { SiteSetupUserAnswer userAnswer = aIterator.next(); userAnswer.setSiteId(siteId); // save to db questionService.saveSiteSetupUserAnswer(userAnswer); } } } /** * Update course site and related realm based on the roster chosen or requested * @param state * @param siteId * @param rp * @param term */ private void updateCourseSiteSections(SessionState state, String siteId, ResourcePropertiesEdit rp, AcademicSession term) { // whether this is in the process of editing a site? boolean editingSite = ((String) state.getAttribute(STATE_SITE_MODE)).equals(SITE_MODE_SITEINFO) ? true : false; List providerCourseList = state.getAttribute(STATE_ADD_CLASS_PROVIDER_CHOSEN) == null ? new ArrayList() : (List) state.getAttribute(STATE_ADD_CLASS_PROVIDER_CHOSEN); int manualAddNumber = 0; if (state.getAttribute(STATE_MANUAL_ADD_COURSE_NUMBER) != null) { manualAddNumber = ((Integer) state.getAttribute(STATE_MANUAL_ADD_COURSE_NUMBER)).intValue(); } List<SectionObject> cmRequestedSections = (List<SectionObject>) state .getAttribute(STATE_CM_REQUESTED_SECTIONS); List<SectionObject> cmAuthorizerSections = (List<SectionObject>) state .getAttribute(STATE_CM_AUTHORIZER_SECTIONS); String realm = SiteService.siteReference(siteId); if ((providerCourseList != null) && (providerCourseList.size() != 0)) { try { AuthzGroup realmEdit = authzGroupService.getAuthzGroup(realm); String providerRealm = buildExternalRealm(siteId, state, providerCourseList, StringUtils.trimToNull(realmEdit.getProviderGroupId())); realmEdit.setProviderGroupId(providerRealm); authzGroupService.save(realmEdit); } catch (GroupNotDefinedException e) { M_log.error(this + ".updateCourseSiteSections: IdUnusedException, not found, or not an AuthzGroup object", e); addAlert(state, rb.getString("java.realm")); } catch (AuthzPermissionException e) { M_log.warn(this + rb.getString("java.notaccess")); addAlert(state, rb.getString("java.notaccess")); } sendSiteNotification(state, getStateSite(state), providerCourseList); //Track add changes trackRosterChanges(org.sakaiproject.site.api.SiteService.EVENT_SITE_ROSTER_ADD, providerCourseList); } if (manualAddNumber != 0) { // set the manual sections to the site property String manualSections = rp.getProperty(PROP_SITE_REQUEST_COURSE) != null ? rp.getProperty(PROP_SITE_REQUEST_COURSE) + "+" : ""; // manualCourseInputs is a list of a list of SectionField List manualCourseInputs = (List) state.getAttribute(STATE_MANUAL_ADD_COURSE_FIELDS); // but we want to feed a list of a list of String (input of // the required fields) for (int j = 0; j < manualAddNumber; j++) { manualSections = manualSections .concat(sectionFieldProvider.getSectionEid(term.getEid(), (List) manualCourseInputs.get(j))) .concat("+"); } // trim the trailing plus sign manualSections = trimTrailingString(manualSections, "+"); rp.addProperty(PROP_SITE_REQUEST_COURSE, manualSections); // send request sendSiteRequest(state, "new", manualAddNumber, manualCourseInputs, "manual"); } if (cmRequestedSections != null && cmRequestedSections.size() > 0 || state.getAttribute(STATE_CM_SELECTED_SECTIONS) != null) { // set the cmRequest sections to the site property String cmRequestedSectionString = ""; if (!editingSite) { // but we want to feed a list of a list of String (input of // the required fields) for (int j = 0; j < cmRequestedSections.size(); j++) { cmRequestedSectionString = cmRequestedSectionString.concat((cmRequestedSections.get(j)).eid) .concat("+"); } // trim the trailing plus sign cmRequestedSectionString = trimTrailingString(cmRequestedSectionString, "+"); sendSiteRequest(state, "new", cmRequestedSections.size(), cmRequestedSections, "cmRequest"); } else { cmRequestedSectionString = rp.getProperty(STATE_CM_REQUESTED_SECTIONS) != null ? (String) rp.getProperty(STATE_CM_REQUESTED_SECTIONS) : ""; // get the selected cm section if (state.getAttribute(STATE_CM_SELECTED_SECTIONS) != null) { List<SectionObject> cmSelectedSections = (List) state.getAttribute(STATE_CM_SELECTED_SECTIONS); if (cmRequestedSectionString.length() != 0) { cmRequestedSectionString = cmRequestedSectionString.concat("+"); } for (int j = 0; j < cmSelectedSections.size(); j++) { cmRequestedSectionString = cmRequestedSectionString.concat((cmSelectedSections.get(j)).eid) .concat("+"); } // trim the trailing plus sign cmRequestedSectionString = trimTrailingString(cmRequestedSectionString, "+"); sendSiteRequest(state, "new", cmSelectedSections.size(), cmSelectedSections, "cmRequest"); } } // update site property if (cmRequestedSectionString.length() > 0) { rp.addProperty(STATE_CM_REQUESTED_SECTIONS, cmRequestedSectionString); } else { rp.removeProperty(STATE_CM_REQUESTED_SECTIONS); } } if (cmAuthorizerSections != null && cmAuthorizerSections.size() > 0 || state.getAttribute(STATE_CM_SELECTED_SECTIONS) != null) { // set the cmAuthorizer sections to the site property String cmAuthorizerSectionString = ""; if (!editingSite) { // but we want to feed a list of a list of String (input of // the required fields) for (int j = 0; j < cmAuthorizerSections.size(); j++) { cmAuthorizerSectionString = cmAuthorizerSectionString.concat((cmAuthorizerSections.get(j)).eid) .concat("+"); } // trim the trailing plus sign cmAuthorizerSectionString = trimTrailingString(cmAuthorizerSectionString, "+"); sendSiteRequest(state, "new", cmAuthorizerSections.size(), cmAuthorizerSections, "cmRequest"); } else { cmAuthorizerSectionString = rp.getProperty(STATE_CM_AUTHORIZER_SECTIONS) != null ? (String) rp.getProperty(STATE_CM_AUTHORIZER_SECTIONS) : ""; // get the selected cm section if (state.getAttribute(STATE_CM_SELECTED_SECTIONS) != null) { List<SectionObject> cmSelectedSections = (List) state.getAttribute(STATE_CM_SELECTED_SECTIONS); if (cmAuthorizerSectionString.length() != 0) { cmAuthorizerSectionString = cmAuthorizerSectionString.concat("+"); } for (int j = 0; j < cmSelectedSections.size(); j++) { cmAuthorizerSectionString = cmAuthorizerSectionString .concat((cmSelectedSections.get(j)).eid).concat("+"); } // trim the trailing plus sign cmAuthorizerSectionString = trimTrailingString(cmAuthorizerSectionString, "+"); sendSiteRequest(state, "new", cmSelectedSections.size(), cmSelectedSections, "cmRequest"); } } // update site property if (cmAuthorizerSectionString.length() > 0) { rp.addProperty(STATE_CM_AUTHORIZER_SECTIONS, cmAuthorizerSectionString); } else { rp.removeProperty(STATE_CM_AUTHORIZER_SECTIONS); } } } /** * Trim the trailing occurance of specified string * @param cmRequestedSectionString * @param trailingString * @return */ private String trimTrailingString(String cmRequestedSectionString, String trailingString) { if (cmRequestedSectionString.endsWith(trailingString)) { cmRequestedSectionString = cmRequestedSectionString.substring(0, cmRequestedSectionString.lastIndexOf(trailingString)); } return cmRequestedSectionString; } /** * buildExternalRealm creates a site/realm id in one of three formats, for a * single section, for multiple sections of the same course, or for a * cross-listing having multiple courses * * @param sectionList * is a Vector of CourseListItem * @param id * The site id */ private String buildExternalRealm(String id, SessionState state, List<String> providerIdList, String existingProviderIdString) { String realm = SiteService.siteReference(id); if (!authzGroupService.allowUpdate(realm)) { addAlert(state, rb.getString("java.rosters")); return null; } List<String> allProviderIdList = new Vector<String>(); // see if we need to keep existing provider settings if (existingProviderIdString != null) { allProviderIdList.addAll(Arrays.asList(groupProvider.unpackId(existingProviderIdString))); } // update the list with newly added providers allProviderIdList.addAll(providerIdList); if (allProviderIdList == null || allProviderIdList.size() == 0) return null; String[] providers = new String[allProviderIdList.size()]; providers = (String[]) allProviderIdList.toArray(providers); String providerId = groupProvider.packId(providers); return providerId; } // buildExternalRealm /** * Notification sent when a course site needs to be set up by Support * */ private void sendSiteRequest(SessionState state, String request, int requestListSize, List requestFields, String fromContext) { User cUser = UserDirectoryService.getCurrentUser(); String sendEmailToRequestee = null; StringBuilder buf = new StringBuilder(); boolean requireAuthorizer = ServerConfigurationService.getString(SAK_PROP_REQUIRE_AUTHORIZER, "true") .equals("true") ? true : false; String emailAuthorizer = ServerConfigurationService.getString(SAK_PROP_EMAIL_AUTHORIZER, ""); // get the request email from configuration String requestEmail = getSetupRequestEmailAddress(); // get the request replyTo email from configuration String requestReplyToEmail = getSetupRequestReplyToEmailAddress(); if (requestEmail != null) { String officialAccountName = ServerConfigurationService.getString("officialAccountName", ""); SiteInfo siteInfo = (SiteInfo) state.getAttribute(STATE_SITE_INFO); Site site = getStateSite(state); String id = site.getId(); String title = site.getTitle(); Time time = TimeService.newTime(); String local_time = time.toStringLocalTime(); String local_date = time.toStringLocalDate(); AcademicSession term = null; boolean termExist = false; if (state.getAttribute(STATE_TERM_SELECTED) != null) { termExist = true; term = (AcademicSession) state.getAttribute(STATE_TERM_SELECTED); } String productionSiteName = ServerConfigurationService.getServerName(); String from = NULL_STRING; String to = NULL_STRING; String headerTo = NULL_STRING; String replyTo = NULL_STRING; String content = NULL_STRING; String sessionUserName = cUser.getDisplayName(); String additional = NULL_STRING; if ("new".equals(request)) { additional = siteInfo.getAdditional(); } else { additional = (String) state.getAttribute(FORM_ADDITIONAL); } boolean isFutureTerm = false; if (state.getAttribute(STATE_FUTURE_TERM_SELECTED) != null && ((Boolean) state.getAttribute(STATE_FUTURE_TERM_SELECTED)).booleanValue()) { isFutureTerm = true; } // there is no offical instructor for future term sites String requestId = (String) state.getAttribute(STATE_SITE_QUEST_UNIQNAME); // SAK-18976:Site Requests Generated by entering instructor's User ID fail to add term properties and fail to send site request approval email List<String> authorizerList = (List) state.getAttribute(STATE_CM_AUTHORIZER_LIST); if (authorizerList == null) { authorizerList = new ArrayList(); } if (requestId != null) { // in case of multiple instructors List instructors = new ArrayList(Arrays.asList(requestId.split(","))); for (Iterator iInstructors = instructors.iterator(); iInstructors.hasNext();) { String instructorId = (String) iInstructors.next(); authorizerList.add(instructorId); } } String requestSectionInfo = ""; // requested sections if ("manual".equals(fromContext)) { requestSectionInfo = addRequestedSectionIntoNotification(state, requestFields); } else if ("cmRequest".equals(fromContext)) { requestSectionInfo = addRequestedCMSectionIntoNotification(state, requestFields); } String authorizerNotified = ""; String authorizerNotNotified = ""; if (!isFutureTerm) { for (Iterator iInstructors = authorizerList.iterator(); iInstructors.hasNext();) { String instructorId = (String) iInstructors.next(); //If emailAuthorizer is defined to be true or if requireAuthorizer is set //If emailAuthrozier is true always send email, if it's unset send if requireAuthrozier is set //Otherwise don't send if (("".equals(emailAuthorizer) && requireAuthorizer) || "true".equals(emailAuthorizer)) { // 1. email to course site authorizer boolean result = userNotificationProvider.notifyCourseRequestAuthorizer(instructorId, requestEmail, requestReplyToEmail, term != null ? term.getTitle() : "", requestSectionInfo, title, id, additional, productionSiteName); if (!result) { // append authorizer who doesn't received an notification authorizerNotNotified += instructorId + ", "; } else { // append authorizer who does received an notification authorizerNotified += instructorId + ", "; } } } } // 2. email to system support team String supportEmailContent = userNotificationProvider.notifyCourseRequestSupport(requestEmail, productionSiteName, request, term != null ? term.getTitle() : "", requestListSize, requestSectionInfo, officialAccountName, title, id, additional, requireAuthorizer, authorizerNotified, authorizerNotNotified); // 3. email to site requeser userNotificationProvider.notifyCourseRequestRequester(requestEmail, supportEmailContent, term != null ? term.getTitle() : ""); // revert the locale to system default rb.setContextLocale(Locale.getDefault()); state.setAttribute(REQUEST_SENT, Boolean.valueOf(true)); } // if // reset locale to user default rb.setContextLocale(null); } // sendSiteRequest private String addRequestedSectionIntoNotification(SessionState state, List requestFields) { StringBuffer buf = new StringBuffer(); // what are the required fields shown in the UI List requiredFields = state.getAttribute(STATE_MANUAL_ADD_COURSE_FIELDS) != null ? (List) state.getAttribute(STATE_MANUAL_ADD_COURSE_FIELDS) : new Vector(); for (int i = 0; i < requiredFields.size(); i++) { List requiredFieldList = (List) requestFields.get(i); for (int j = 0; j < requiredFieldList.size(); j++) { SectionField requiredField = (SectionField) requiredFieldList.get(j); buf.append(requiredField.getLabelKey() + "\t" + requiredField.getValue() + "\n"); } buf.append("\n"); } return buf.toString(); } private String addRequestedCMSectionIntoNotification(SessionState state, List cmRequestedSections) { StringBuffer buf = new StringBuffer(); // what are the required fields shown in the UI for (int i = 0; i < cmRequestedSections.size(); i++) { SectionObject so = (SectionObject) cmRequestedSections.get(i); buf.append(so.getTitle() + "(" + so.getEid() + ")" + so.getCategory() + "\n"); } return buf.toString(); } /** * Notification sent when a course site is set up automatcally * */ private void sendSiteNotification(SessionState state, Site site, List notifySites) { boolean courseSite = SiteTypeUtil.isCourseSite(site.getType()); String term_name = ""; if (state.getAttribute(STATE_TERM_SELECTED) != null) { term_name = ((AcademicSession) state.getAttribute(STATE_TERM_SELECTED)).getEid(); } // get the request email from configuration String requestEmail = getSetupRequestEmailAddress(); User currentUser = UserDirectoryService.getCurrentUser(); // read from configuration whether to send out site notification emails, which defaults to be true boolean sendSiteNotificationChoice = ServerConfigurationService .getBoolean("site.setup.creation.notification", true); if (requestEmail != null && currentUser != null && sendSiteNotificationChoice) { userNotificationProvider.notifySiteCreation(site, notifySites, courseSite, term_name, requestEmail); } // if // reset locale to user default rb.setContextLocale(null); } // sendSiteNotification /** * doCancel called when "eventSubmit_doCancel_create" is in the request * parameters to c */ public void doCancel_create(RunData data) { // Don't put current form data in state, just return to the previous // template SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); removeAddClassContext(state); state.setAttribute(STATE_TEMPLATE_INDEX, "0"); if (SITE_MODE_HELPER.equals(state.getAttribute(STATE_SITE_MODE))) { state.setAttribute(STATE_SITE_MODE, SITE_MODE_HELPER_DONE); state.setAttribute(SiteHelper.SITE_CREATE_CANCELLED, Boolean.TRUE); } else { state.setAttribute(STATE_TEMPLATE_INDEX, "0"); } resetVisitedTemplateListToIndex(state, (String) state.getAttribute(STATE_TEMPLATE_INDEX)); // remove state variables in tool editing removeEditToolState(state); } // doCancel_create /** * doCancel called when "eventSubmit_doCancel" is in the request parameters * to c int index = Integer.valueOf(params.getString * ("templateIndex")).intValue(); */ public void doCancel(RunData data) { // Don't put current form data in state, just return to the previous // template SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); ParameterParser params = data.getParameters(); state.removeAttribute(STATE_MESSAGE); String currentIndex = (String) state.getAttribute(STATE_TEMPLATE_INDEX); String backIndex = params.getString("back"); state.setAttribute(STATE_TEMPLATE_INDEX, backIndex); if ("4".equals(currentIndex)) { state.removeAttribute(STATE_TOOL_EMAIL_ADDRESS); state.removeAttribute(STATE_MESSAGE); removeEditToolState(state); } else if (getStateSite(state) != null && ("13".equals(currentIndex) || "14".equals(currentIndex))) { MathJaxEnabler.removeMathJaxAllowedAttributeFromState(state); // SAK-22384 state.setAttribute(STATE_TEMPLATE_INDEX, "12"); } else if ("15".equals(currentIndex)) { params = data.getParameters(); state.setAttribute(STATE_TEMPLATE_INDEX, params.getString("cancelIndex")); removeEditToolState(state); } // htripath: added '"45".equals(currentIndex)' for import from file // cancel else if ("45".equals(currentIndex)) { state.setAttribute(STATE_TEMPLATE_INDEX, "12"); } else if ("4".equals(currentIndex)) { // from adding class if (((String) state.getAttribute(STATE_SITE_MODE)).equalsIgnoreCase(SITE_MODE_SITESETUP)) { state.setAttribute(STATE_TEMPLATE_INDEX, "0"); } else if (((String) state.getAttribute(STATE_SITE_MODE)).equalsIgnoreCase(SITE_MODE_SITEINFO)) { state.setAttribute(STATE_TEMPLATE_INDEX, "18"); } } else if ("27".equals(currentIndex) || "28".equals(currentIndex) || "59".equals(currentIndex) || "60".equals(currentIndex)) { // from import if (((String) state.getAttribute(STATE_SITE_MODE)).equalsIgnoreCase(SITE_MODE_SITESETUP)) { // worksite setup if (getStateSite(state) == null) { // in creating new site process state.setAttribute(STATE_TEMPLATE_INDEX, "0"); } else { // in editing site process state.setAttribute(STATE_TEMPLATE_INDEX, "12"); } } else if (((String) state.getAttribute(STATE_SITE_MODE)).equalsIgnoreCase(SITE_MODE_SITEINFO)) { // site info state.setAttribute(STATE_TEMPLATE_INDEX, "12"); } state.removeAttribute(STATE_IMPORT_SITE_TOOL); state.removeAttribute(STATE_IMPORT_SITES); } else if ("26".equals(currentIndex)) { if (((String) state.getAttribute(STATE_SITE_MODE)).equalsIgnoreCase(SITE_MODE_SITESETUP) && getStateSite(state) == null) { // from creating site state.setAttribute(STATE_TEMPLATE_INDEX, "0"); } else { // from revising site state.setAttribute(STATE_TEMPLATE_INDEX, "12"); } removeEditToolState(state); } else if ("37".equals(currentIndex) || "44".equals(currentIndex) || "53".equals(currentIndex) || "36".equals(currentIndex)) { // cancel back to edit class view state.removeAttribute(STATE_TERM_SELECTED); removeAddClassContext(state); state.setAttribute(STATE_TEMPLATE_INDEX, "43"); } // if all fails to match else if (isTemplateVisited(state, "12")) { // go to site info list view state.setAttribute(STATE_TEMPLATE_INDEX, "12"); } else { // go to WSetup list view state.setAttribute(STATE_TEMPLATE_INDEX, "0"); } resetVisitedTemplateListToIndex(state, (String) state.getAttribute(STATE_TEMPLATE_INDEX)); } // doCancel /** * doMenu_customize is called when "eventSubmit_doBack" is in the request * parameters Pass parameter to actionForTemplate to request action for * backward direction */ public void doMenu_customize(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); state.setAttribute(STATE_TEMPLATE_INDEX, "15"); }// doMenu_customize /** * doBack_to_list cancels an outstanding site edit, cleans state and returns * to the site list * */ public void doBack_to_list(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); Site site = getStateSite(state); if (site != null) { Hashtable h = (Hashtable) state.getAttribute(STATE_PAGESIZE_SITEINFO); h.put(site.getId(), state.getAttribute(STATE_PAGESIZE)); state.setAttribute(STATE_PAGESIZE_SITEINFO, h); } // restore the page size for Worksite setup tool if (state.getAttribute(STATE_PAGESIZE_SITESETUP) != null) { state.setAttribute(STATE_PAGESIZE, state.getAttribute(STATE_PAGESIZE_SITESETUP)); state.removeAttribute(STATE_PAGESIZE_SITESETUP); } cleanState(state); setupFormNamesAndConstants(state); state.setAttribute(STATE_TEMPLATE_INDEX, "0"); // reset resetVisitedTemplateListToIndex(state, "0"); } // doBack_to_list /** * reset to sublist with index as the last item * @param state * @param index */ private void resetVisitedTemplateListToIndex(SessionState state, String index) { if (state.getAttribute(STATE_VISITED_TEMPLATES) != null) { List<String> l = (List<String>) state.getAttribute(STATE_VISITED_TEMPLATES); if (l != null && l.indexOf(index) >= 0 && l.indexOf(index) < l.size()) { state.setAttribute(STATE_VISITED_TEMPLATES, l.subList(0, l.indexOf(index) + 1)); } } } /** * toolId might be of form original tool id concatenated with number * find whether there is an counterpart in the the multipleToolIdSet * @param state * @param toolId * @return */ private String findOriginalToolId(SessionState state, String toolId) { // treat home tool differently if (toolId.equals(TOOL_ID_HOME) || SITE_INFO_TOOL_ID.equals(toolId)) { return toolId; } else { Set categories = new HashSet(); categories.add((String) state.getAttribute(STATE_SITE_TYPE)); Set toolRegistrationList = ToolManager.findTools(categories, null); String rv = null; if (toolRegistrationList != null) { for (Iterator i = toolRegistrationList.iterator(); rv == null && i.hasNext();) { Tool tool = (Tool) i.next(); String tId = tool.getId(); rv = originalToolId(toolId, tId); } } return rv; } } // replace fake tool ids with real ones. Don't duplicate, since several fake tool ids may appear for the same real one // it's far from clear that we need to be using fake tool ids at all. But I don't know the code well enough // to get rid of the fakes completely. // modified to exclude nulls as sakai.assignment is still in the list (as of Nov 2014) and is unresolvable private List<String> originalToolIds(List<String> toolIds, SessionState state) { Set<String> found = new HashSet<String>(); List<String> rv = new ArrayList<String>(); for (String toolId : toolIds) { String origToolId = findOriginalToolId(state, toolId); if (StringUtils.isNotBlank(origToolId) && !found.contains(origToolId)) { rv.add(origToolId); found.add(origToolId); } } return rv; } private String originalToolId(String toolId, String toolRegistrationId) { String rv = null; if (toolId.equals(toolRegistrationId)) { rv = toolRegistrationId; } else if (toolId.indexOf(toolRegistrationId) != -1 && isMultipleInstancesAllowed(toolRegistrationId)) { // the multiple tool id format is of SITE_IDTOOL_IDx, where x is an intger >= 1 if (toolId.endsWith(toolRegistrationId)) { // get the site id part out String uuid = toolId.replaceFirst(toolRegistrationId, ""); if (uuid != null && uuid.length() == UUID_LENGTH) rv = toolRegistrationId; } else { String suffix = toolId.substring(toolId.indexOf(toolRegistrationId) + toolRegistrationId.length()); try { Integer.parseInt(suffix); rv = toolRegistrationId; } catch (Exception e) { // not the right tool id M_log.debug(this + ".findOriginalToolId not matching tool id = " + toolRegistrationId + " original tool id=" + toolId + e.getMessage(), e); } } } return rv; } /** * Read from tool registration whether multiple registration is allowed for this tool * @param toolId * @return */ private boolean isMultipleInstancesAllowed(String toolId) { Tool tool = ToolManager.getTool(toolId); if (tool != null) { Properties tProperties = tool.getRegisteredConfig(); return (tProperties.containsKey("allowMultipleInstances") && tProperties.getProperty("allowMultipleInstances").equalsIgnoreCase(Boolean.TRUE.toString())) ? true : false; } return false; } private HashMap<String, String> getMultiToolConfiguration(String toolId, ToolConfiguration toolConfig) { HashMap<String, String> rv = new HashMap<String, String>(); // read attribute list from configuration file ArrayList<String> attributes = new ArrayList<String>(); String attributesConfig = ServerConfigurationService.getString(CONFIG_TOOL_ATTRIBUTE + toolId); if (attributesConfig != null && attributesConfig.length() > 0) { // read attributes from config file attributes = new ArrayList(Arrays.asList(attributesConfig.split(","))); } else { if (toolId.equals(NEWS_TOOL_ID)) { // default setting for News tool attributes.add(NEWS_TOOL_CHANNEL_CONFIG); } else if (toolId.equals(WEB_CONTENT_TOOL_ID)) { // default setting for Web Content tool attributes.add(WEB_CONTENT_TOOL_SOURCE_CONFIG); } } // read the defaul attribute setting from configuration ArrayList<String> defaultValues = new ArrayList<String>(); String defaultValueConfig = ServerConfigurationService.getString(CONFIG_TOOL_ATTRIBUTE_DEFAULT + toolId); if (defaultValueConfig != null && defaultValueConfig.length() > 0) { defaultValues = new ArrayList(Arrays.asList(defaultValueConfig.split(","))); } else { // otherwise, treat News tool and Web Content tool differently if (toolId.equals(NEWS_TOOL_ID)) { // default value defaultValues.add(NEWS_TOOL_CHANNEL_CONFIG_VALUE); } else if (toolId.equals(WEB_CONTENT_TOOL_ID)) { // default value defaultValues.add(WEB_CONTENT_TOOL_SOURCE_CONFIG_VALUE); } } if (attributes != null && attributes.size() > 0 && defaultValues != null && defaultValues.size() > 0 && attributes.size() == defaultValues.size()) { for (int i = 0; i < attributes.size(); i++) { String attribute = attributes.get(i); // check to see the current settings first Properties config = toolConfig != null ? toolConfig.getConfig() : null; if (config != null && config.containsKey(attribute)) { rv.put(attribute, config.getProperty(attribute)); } else { // set according to the default setting rv.put(attribute, defaultValues.get(i)); } } } return rv; } /** * The triage function for saving modified features page * @param data */ public void doAddRemoveFeatureConfirm_option(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); ParameterParser params = data.getParameters(); String option = params.getString("option"); if ("revise".equals(option)) { // save the modified features doSave_revised_features(state, params); } else if ("back".equals(option)) { // back a step doBack(data); } else if ("cancel".equals(option)) { // cancel out doCancel(data); } } /** * doSave_revised_features */ public void doSave_revised_features(SessionState state, ParameterParser params) { Site site = getStateSite(state); saveFeatures(params, state, site); if (state.getAttribute(STATE_MESSAGE) == null) { // clean state variables state.removeAttribute(STATE_TOOL_REGISTRATION_SELECTED_LIST); state.removeAttribute(STATE_TOOL_REGISTRATION_OLD_SELECTED_LIST); state.removeAttribute(STATE_TOOL_REGISTRATION_OLD_SELECTED_HOME); state.removeAttribute(STATE_MULTIPLE_TOOL_ID_SET); state.removeAttribute(STATE_MULTIPLE_TOOL_ID_TITLE_MAP); state.setAttribute(STATE_SITE_INSTANCE_ID, site.getId()); state.setAttribute(STATE_TEMPLATE_INDEX, params.getString("continue")); resetVisitedTemplateListToIndex(state, (String) state.getAttribute(STATE_TEMPLATE_INDEX)); // refresh the whole page scheduleTopRefresh(); } } // doSave_revised_features /** * doMenu_siteInfo_cancel_access */ public void doMenu_siteInfo_cancel_access(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); state.removeAttribute(STATE_SELECTED_USER_LIST); state.setAttribute(STATE_TEMPLATE_INDEX, "12"); } // doMenu_siteInfo_cancel_access /** * doMenu_siteInfo_importSelection */ public void doMenu_siteInfo_importSelection(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); // get the tools siteToolsIntoState(state); if (state.getAttribute(STATE_MESSAGE) == null) { state.setAttribute(STATE_TEMPLATE_INDEX, "58"); } } // doMenu_siteInfo_importSelection /** * doMenu_siteInfo_import */ public void doMenu_siteInfo_import(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); // get the tools siteToolsIntoState(state); if (state.getAttribute(STATE_MESSAGE) == null) { state.setAttribute(STATE_TEMPLATE_INDEX, "28"); } } // doMenu_siteInfo_import /** * doMenu_siteInfo_import_user */ public void doMenu_siteInfo_import_user(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); if (state.getAttribute(STATE_MESSAGE) == null) { state.setAttribute(STATE_TEMPLATE_INDEX, "61"); // import users } } // doMenu_siteInfo_import_user public void doMenu_siteInfo_importMigrate(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); // get the tools siteToolsIntoState(state); if (state.getAttribute(STATE_MESSAGE) == null) { state.setAttribute(STATE_TEMPLATE_INDEX, "59"); } } // doMenu_siteInfo_importMigrate /** * doMenu_siteInfo_editClass */ public void doMenu_siteInfo_editClass(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); state.setAttribute(STATE_TEMPLATE_INDEX, "43"); } // doMenu_siteInfo_editClass /** * doMenu_siteInfo_addClass */ public void doMenu_siteInfo_addClass(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); Site site = getStateSite(state); String termEid = site.getProperties().getProperty(Site.PROP_SITE_TERM_EID); if (termEid == null) { // no term eid stored, need to get term eid from the term title String termTitle = site.getProperties().getProperty(Site.PROP_SITE_TERM); List asList = cms.getAcademicSessions(); if (termTitle != null && asList != null) { boolean found = false; for (int i = 0; i < asList.size() && !found; i++) { AcademicSession as = (AcademicSession) asList.get(i); if (as.getTitle().equals(termTitle)) { termEid = as.getEid(); site.getPropertiesEdit().addProperty(Site.PROP_SITE_TERM_EID, termEid); try { SiteService.save(site); } catch (Exception e) { M_log.error(this + ".doMenu_siteinfo_addClass: " + e.getMessage() + site.getId(), e); } found = true; } } } } if (termEid != null) { state.setAttribute(STATE_TERM_SELECTED, cms.getAcademicSession(termEid)); try { List sections = prepareCourseAndSectionListing(UserDirectoryService.getCurrentUser().getEid(), cms.getAcademicSession(termEid).getEid(), state); isFutureTermSelected(state); if (sections != null && sections.size() > 0) state.setAttribute(STATE_TERM_COURSE_LIST, sections); } catch (Exception e) { M_log.error(this + ".doMenu_siteinfo_addClass: " + e.getMessage() + termEid, e); } } else { List currentTerms = cms.getCurrentAcademicSessions(); if (currentTerms != null && !currentTerms.isEmpty()) { // if the term information is missing for the site, assign it to the first current term in list state.setAttribute(STATE_TERM_SELECTED, currentTerms.get(0)); } } state.setAttribute(STATE_TEMPLATE_INDEX, "36"); } // doMenu_siteInfo_addClass /** * doMenu_siteInfo_duplicate */ public void doMenu_siteInfo_duplicate(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); if (state.getAttribute(STATE_MESSAGE) == null) { state.setAttribute(STATE_TEMPLATE_INDEX, "29"); } } // doMenu_siteInfo_import /** * doMenu_edit_site_info * */ public void doMenu_edit_site_info(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); sitePropertiesIntoState(state); if (state.getAttribute(STATE_MESSAGE) == null) { state.setAttribute(STATE_TEMPLATE_INDEX, "13"); } } // doMenu_edit_site_info /** * doMenu_edit_site_tools * */ public void doMenu_edit_site_tools(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); // Clean up state on our first entry from a shortcut String panel = data.getParameters().getString("panel"); if ("Shortcut".equals(panel)) cleanState(state); // get the tools siteToolsIntoState(state); if (state.getAttribute(STATE_MESSAGE) == null) { state.setAttribute(STATE_TEMPLATE_INDEX, "4"); if (state.getAttribute(STATE_INITIALIZED) == null) { state.setAttribute(STATE_OVERRIDE_TEMPLATE_INDEX, "4"); } } } // doMenu_edit_site_tools /** * doMenu_edit_site_access * */ public void doMenu_edit_site_access(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); try { Site site = getStateSite(state); state.setAttribute(STATE_SITE_ACCESS_PUBLISH, Boolean.valueOf(site.isPublished())); state.setAttribute(STATE_SITE_ACCESS_INCLUDE, Boolean.valueOf(site.isPubView())); boolean joinable = site.isJoinable(); state.setAttribute(STATE_JOINABLE, Boolean.valueOf(joinable)); String joinerRole = site.getJoinerRole(); if (joinerRole == null || joinerRole.length() == 0) { String[] joinerRoles = ServerConfigurationService.getStrings("siteinfo.default_joiner_role"); Set<Role> roles = site.getRoles(); if (roles != null && joinerRole != null && joinerRoles.length > 0) { // find the role match for (Role r : roles) { for (int i = 0; i < joinerRoles.length; i++) { if (r.getId().equalsIgnoreCase(joinerRoles[i])) { joinerRole = r.getId(); break; } } if (joinerRole != null) { break; } } } } state.setAttribute(STATE_JOINERROLE, joinerRole); // bjones86 - SAK-24423 - update state for joinable site settings JoinableSiteSettings.updateStateFromSitePropertiesOnEditAccessOrNewSite(site.getProperties(), state); } catch (Exception e) { M_log.warn(this + " doMenu_edit_site_access problem of getting site" + e.getMessage()); } if (state.getAttribute(STATE_MESSAGE) == null) { state.setAttribute(STATE_TEMPLATE_INDEX, "18"); } } // doMenu_edit_site_access /** * Back to worksite setup's list view * */ public void doBack_to_site_list(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); state.removeAttribute(STATE_SELECTED_USER_LIST); state.removeAttribute(STATE_SITE_TYPE); state.removeAttribute(STATE_SITE_INSTANCE_ID); state.setAttribute(STATE_TEMPLATE_INDEX, "0"); // reset resetVisitedTemplateListToIndex(state, "0"); } // doBack_to_site_list /** * doSave_site_info * */ public void doSave_siteInfo(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); Site Site = getStateSite(state); ResourcePropertiesEdit siteProperties = Site.getPropertiesEdit(); String site_type = (String) state.getAttribute(STATE_SITE_TYPE); SiteInfo siteInfo = (SiteInfo) state.getAttribute(STATE_SITE_INFO); if (siteTitleEditable(state, SiteTypeUtil.getTargetSiteType(site_type))) { Site.setTitle(siteInfo.title); } //Process description so it doesn't give an error on home siteInfo.description = FormattedText.processFormattedText(siteInfo.description, new StringBuilder()); Site.setDescription(siteInfo.description); Site.setShortDescription(siteInfo.short_description); if (site_type != null) { // set icon url for course setAppearance(state, Site, siteInfo.iconUrl); } // site contact information String contactName = siteInfo.site_contact_name; if (contactName != null) { siteProperties.addProperty(Site.PROP_SITE_CONTACT_NAME, contactName); } String contactEmail = siteInfo.site_contact_email; if (contactEmail != null) { siteProperties.addProperty(Site.PROP_SITE_CONTACT_EMAIL, contactEmail); } Collection<String> oldAliasIds = getSiteReferenceAliasIds(Site); boolean updateSiteRefAliases = aliasesEditable(state, Site.getId()); if (updateSiteRefAliases) { setSiteReferenceAliases(state, Site.getId()); } /// site language information String locale_string = (String) state.getAttribute("locale_string"); siteProperties.removeProperty(PROP_SITE_LANGUAGE); siteProperties.addProperty(PROP_SITE_LANGUAGE, locale_string); // SAK-22384 mathjax support MathJaxEnabler.prepareMathJaxAllowedSettingsForSave(Site, state); if (state.getAttribute(STATE_MESSAGE) == null) { try { SiteService.save(Site); } catch (IdUnusedException e) { // TODO: } catch (PermissionException e) { // TODO: } // back to site info view state.setAttribute(STATE_TEMPLATE_INDEX, "12"); // Need to refresh the entire page because, e.g. the current site's name // may have changed. This is problematic, though, b/c the current // top-level portal URL may reference a just-deleted alias. A temporary // alias translation map is one option, but it is difficult to know when // to clean up. So we send a redirect instead of just scheduling // a reload. // // One problem with this is we have no good way to know what the // top-level portal handler should actually be. We also don't have a // particularly good way of knowing how the portal expects to receive // page references. We can't just use SitePage.getUrl() because that // method assumes that site reference roots are identical to portal // handler URL fragments, which is not guaranteed. Hence the approach // below which tries to guess at the right portal handler, but just // punts on page reference roots, using SiteService.PAGE_SUBTYPE for // that portion of the URL // // None of this helps other users who may try to reload an aliased site // URL that no longer resolves. if (updateSiteRefAliases) { sendParentRedirect( (HttpServletResponse) ThreadLocalManager.get(RequestFilter.CURRENT_HTTP_RESPONSE), getDefaultSiteUrl(ToolManager.getCurrentPlacement().getContext()) + "/" + SiteService.PAGE_SUBTYPE + "/" + ((ToolConfiguration) ToolManager.getCurrentPlacement()).getPageId()); } else { scheduleTopRefresh(); } } } // doSave_siteInfo /** * Check to see whether the site's title is editable or not * @param state * @param site_type * @return */ private boolean siteTitleEditable(SessionState state, String site_type) { return site_type != null && ((state.getAttribute(TITLE_NOT_EDITABLE_SITE_TYPE) != null && !((List) state.getAttribute(TITLE_NOT_EDITABLE_SITE_TYPE)).contains(site_type))); } /** * Tests if the alias editing feature has been enabled * ({@link #aliasEditingEnabled(SessionState, String)}) and that * current user has set/remove aliasing permissions for the given * {@link Site} ({@link #aliasEditingPermissioned(SessionState, String)}). * * <p>(Method name and signature is an attempt to be consistent with * {@link #siteTitleEditable(SessionState, String)}).</p> * * @param state not used * @param siteId a site identifier (not a {@link Reference}); must not be <code>null</code> * @return */ private boolean aliasesEditable(SessionState state, String siteId) { return aliasEditingEnabled(state, siteId) && aliasEditingPermissioned(state, siteId); } /** * Tests if alias editing has been enabled by configuration. This is * independent of any permissioning considerations. Also note that this * feature is configured separately from alias assignment during worksite * creation. This feature applies exclusively to alias edits and deletes * against existing sites. * * <p>(Method name and signature is an attempt to be consistent with * {@link #siteTitleEditable(SessionState, String)}).</p> * * @see #aliasAssignmentForNewSitesEnabled(SessionState) * @param state * @param siteId * @return */ private boolean aliasEditingEnabled(SessionState state, String siteId) { return ServerConfigurationService.getBoolean("site-manage.enable.alias.edit", false); } /** * Tests if alias assignment for new sites has been enabled by configuration. * This is independent of any permissioning considerations. * * <p>(Method name and signature is an attempt to be consistent with * {@link #siteTitleEditable(SessionState, String)}).</p> * * @param state * @param siteId * @return */ private boolean aliasAssignmentForNewSitesEnabled(SessionState state) { return ServerConfigurationService.getBoolean("site-manage.enable.alias.new", false); } /** * Tests if the current user has set and remove permissions for aliases * of the given site. <p>(Method name and signature is an attempt to be * consistent with {@link #siteTitleEditable(SessionState, String)}).</p> * * @param state * @param siteId * @return */ private boolean aliasEditingPermissioned(SessionState state, String siteId) { String siteRef = SiteService.siteReference(siteId); return aliasService.allowSetAlias("", siteRef) && aliasService.allowRemoveTargetAliases(siteRef); } /** * init * */ private void init(VelocityPortlet portlet, RunData data, SessionState state) { state.setAttribute(STATE_ACTION, "SiteAction"); setupFormNamesAndConstants(state); if (state.getAttribute(STATE_PAGESIZE_SITEINFO) == null) { state.setAttribute(STATE_PAGESIZE_SITEINFO, new Hashtable()); } if (SITE_MODE_SITESETUP.equalsIgnoreCase((String) state.getAttribute(STATE_SITE_MODE))) { state.setAttribute(STATE_TEMPLATE_INDEX, "0"); // need to watch out for the config question.xml existence. // read the file and put it to backup folder. if (SiteSetupQuestionFileParser.isConfigurationXmlAvailable()) { SiteSetupQuestionFileParser.updateConfig(); } } else if (SITE_MODE_HELPER.equalsIgnoreCase((String) state.getAttribute(STATE_SITE_MODE))) { state.setAttribute(STATE_TEMPLATE_INDEX, "1"); } else if (SITE_MODE_SITEINFO.equalsIgnoreCase((String) state.getAttribute(STATE_SITE_MODE))) { String siteId = ToolManager.getCurrentPlacement().getContext(); getReviseSite(state, siteId); Hashtable h = (Hashtable) state.getAttribute(STATE_PAGESIZE_SITEINFO); if (!h.containsKey(siteId)) { // update h.put(siteId, Integer.valueOf(200)); state.setAttribute(STATE_PAGESIZE_SITEINFO, h); state.setAttribute(STATE_PAGESIZE, Integer.valueOf(200)); } } if (state.getAttribute(STATE_SITE_TYPES) == null) { PortletConfig config = portlet.getPortletConfig(); // all site types (SITE_DEFAULT_LIST overrides tool config) String t = StringUtils.trimToNull(SITE_DEFAULT_LIST); if (t == null) t = StringUtils.trimToNull(config.getInitParameter("siteTypes")); if (t != null) { List types = new ArrayList(Arrays.asList(t.split(","))); if (cms == null) { // if there is no CourseManagementService, disable the process of creating course site List<String> courseTypes = SiteTypeUtil.getCourseSiteTypes(); types.remove(courseTypes); } state.setAttribute(STATE_SITE_TYPES, types); } else { t = (String) state.getAttribute(SiteHelper.SITE_CREATE_SITE_TYPES); if (t != null) { state.setAttribute(STATE_SITE_TYPES, new ArrayList(Arrays.asList(t.split(",")))); } else { state.setAttribute(STATE_SITE_TYPES, new Vector()); } } } // show UI for adding non-official participant(s) or not // if nonOfficialAccount variable is set to be false inside sakai.properties file, do not show the UI section for adding them. // the setting defaults to be true if (state.getAttribute(ADD_NON_OFFICIAL_PARTICIPANT) == null) { state.setAttribute(ADD_NON_OFFICIAL_PARTICIPANT, ServerConfigurationService.getString("nonOfficialAccount", "true")); } if (state.getAttribute(STATE_VISITED_TEMPLATES) == null) { List<String> templates = new Vector<String>(); if (((String) state.getAttribute(STATE_SITE_MODE)).equalsIgnoreCase(SITE_MODE_SITESETUP)) { templates.add("0"); // the default page of WSetup tool } else if (((String) state.getAttribute(STATE_SITE_MODE)).equalsIgnoreCase(SITE_MODE_SITEINFO)) { templates.add("12");// the default page of Site Info tool } state.setAttribute(STATE_VISITED_TEMPLATES, templates); } if (state.getAttribute(STATE_SITE_TITLE_MAX) == null) { int siteTitleMaxLength = ServerConfigurationService.getInt("site.title.maxlength", 25); state.setAttribute(STATE_SITE_TITLE_MAX, siteTitleMaxLength); } } // init public void doNavigate_to_site(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); String siteId = StringUtils.trimToNull(data.getParameters().getString("option")); if (siteId != null) { getReviseSite(state, siteId); } else { doBack_to_list(data); } } // doNavigate_to_site /** * Get site information for revise screen */ private void getReviseSite(SessionState state, String siteId) { if (state.getAttribute(STATE_SELECTED_USER_LIST) == null) { state.setAttribute(STATE_SELECTED_USER_LIST, new Vector()); } List sites = (List) state.getAttribute(STATE_SITES); try { Site site = SiteService.getSite(siteId); state.setAttribute(STATE_SITE_INSTANCE_ID, site.getId()); if (sites != null) { int pos = -1; for (int index = 0; index < sites.size() && pos == -1; index++) { if (((Site) sites.get(index)).getId().equals(siteId)) { pos = index; } } // has any previous site in the list? if (pos > 0) { state.setAttribute(STATE_PREV_SITE, sites.get(pos - 1)); } else { state.removeAttribute(STATE_PREV_SITE); } // has any next site in the list? if (pos < sites.size() - 1) { state.setAttribute(STATE_NEXT_SITE, sites.get(pos + 1)); } else { state.removeAttribute(STATE_NEXT_SITE); } } String type = site.getType(); if (type == null) { if (state.getAttribute(STATE_DEFAULT_SITE_TYPE) != null) { type = (String) state.getAttribute(STATE_DEFAULT_SITE_TYPE); } } state.setAttribute(STATE_SITE_TYPE, type); } catch (IdUnusedException e) { M_log.error(this + ".getReviseSite: " + e.toString() + " site id = " + siteId, e); } // one site has been selected state.setAttribute(STATE_TEMPLATE_INDEX, "12"); } // getReviseSite /** * when user clicks "join" for a joinable set * @param data */ public void doJoinableSet(RunData data) { ParameterParser params = data.getParameters(); String groupRef = params.getString("joinable-group-ref"); Site currentSite; try { currentSite = SiteService.getSite(ToolManager.getCurrentPlacement().getContext()); if (currentSite != null) { Group siteGroup = currentSite.getGroup(groupRef); //make sure its a joinable set: String joinableSet = siteGroup.getProperties().getProperty(Group.GROUP_PROP_JOINABLE_SET); if (joinableSet != null && !"".equals(joinableSet.trim())) { //check that the max limit hasn't been reached: int max = 0; try { max = Integer .parseInt(siteGroup.getProperties().getProperty(Group.GROUP_PROP_JOINABLE_SET_MAX)); AuthzGroup group = authzGroupService.getAuthzGroup(groupRef); int size = group.getMembers().size(); if (size < max) { //check that the user isn't already a member String userId = UserDirectoryService.getCurrentUser().getId(); boolean found = false; for (Member member : group.getMembers()) { if (member.getUserId().equals(userId)) { found = true; break; } } if (!found) { // add current user as the maintainer Member member = currentSite.getMember(userId); if (member != null) { siteGroup.addMember(userId, member.getRole().getId(), true, false); SecurityAdvisor yesMan = new SecurityAdvisor() { public SecurityAdvice isAllowed(String userId, String function, String reference) { return SecurityAdvice.ALLOWED; } }; try { SecurityService.pushAdvisor(yesMan); commitSite(currentSite); } catch (Exception e) { M_log.debug(e); } finally { SecurityService.popAdvisor(); } } } } } catch (Exception e) { M_log.debug("Error adding user to group: " + groupRef + ", " + e.getMessage(), e); } } } } catch (IdUnusedException e) { M_log.debug("Error adding user to group: " + groupRef + ", " + e.getMessage(), e); } } /** * when user clicks "join" for a joinable set * @param data */ public void doUnjoinableSet(RunData data) { ParameterParser params = data.getParameters(); String groupRef = params.getString("group-ref"); Site currentSite; try { currentSite = SiteService.getSite(ToolManager.getCurrentPlacement().getContext()); if (currentSite != null) { Group siteGroup = currentSite.getGroup(groupRef); //make sure its a joinable set: String joinableSet = siteGroup.getProperties().getProperty(Group.GROUP_PROP_JOINABLE_SET); if (joinableSet != null && !"".equals(joinableSet.trim())) { try { AuthzGroup group = authzGroupService.getAuthzGroup(groupRef); //check that the user is already a member String userId = UserDirectoryService.getCurrentUser().getId(); boolean found = false; for (Member member : group.getMembers()) { if (member.getUserId().equals(userId)) { found = true; break; } } if (found) { // remove current user as the maintainer Member member = currentSite.getMember(userId); if (member != null) { siteGroup.removeMember(userId); SecurityAdvisor yesMan = new SecurityAdvisor() { public SecurityAdvice isAllowed(String userId, String function, String reference) { return SecurityAdvice.ALLOWED; } }; try { SecurityService.pushAdvisor(yesMan); commitSite(currentSite); } catch (Exception e) { M_log.debug(e); } finally { SecurityService.popAdvisor(); } } } } catch (Exception e) { M_log.debug("Error removing user to group: " + groupRef + ", " + e.getMessage(), e); } } } } catch (IdUnusedException e) { M_log.debug("Error removing user to group: " + groupRef + ", " + e.getMessage(), e); } } /** * SAK 23029 - iterate through changed partiants to see how many would have maintain role if all roles, status and deletion changes went through * */ private List<Participant> testProposedUpdates(List<Participant> participants, ParameterParser params, String maintainRole) { List<Participant> maintainersAfterUpdates = new ArrayList<Participant>(); // create list of all partcipants that have been 'Charles Bronson-ed' Set<String> removedParticipantIds = new HashSet(); Set<String> deactivatedParticipants = new HashSet(); if (params.getStrings("selectedUser") != null) { List removals = new ArrayList(Arrays.asList(params.getStrings("selectedUser"))); for (int i = 0; i < removals.size(); i++) { String rId = (String) removals.get(i); removedParticipantIds.add(rId); } } // create list of all participants that have been deactivated for (Participant statusParticipant : participants) { String activeGrantId = statusParticipant.getUniqname(); String activeGrantField = "activeGrant" + activeGrantId; if (params.getString(activeGrantField) != null) { boolean activeStatus = params.getString(activeGrantField).equalsIgnoreCase("true") ? true : false; if (activeStatus == false) { deactivatedParticipants.add(activeGrantId); } } } // now add only those partcipants whose new/current role is maintainer, is (still) active, and not marked for deletion for (Participant roleParticipant : participants) { String id = roleParticipant.getUniqname(); String roleId = "role" + id; String newRole = params.getString(roleId); if ((deactivatedParticipants.contains(id) == false) && roleParticipant.isActive() != false) { // skip any that are not already inactive or are not candidates for deactivation if (removedParticipantIds.contains(id) == false) { if (newRole != null) { if (newRole.equals(maintainRole)) { maintainersAfterUpdates.add(roleParticipant); } } else { // participant has no new role; was participant already maintainer? if (roleParticipant.getRole().equals(maintainRole)) { maintainersAfterUpdates.add(roleParticipant); } } } } } return maintainersAfterUpdates; } /** * doUpdate_participant * */ public void doUpdate_participant(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); ParameterParser params = data.getParameters(); Site s = getStateSite(state); String realmId = SiteService.siteReference(s.getId()); // list of updated users List<String> userUpdated = new Vector<String>(); // list of all removed user List<String> usersDeleted = new Vector<String>(); if (authzGroupService.allowUpdate(realmId) || SiteService.allowUpdateSiteMembership(s.getId())) { try { // init variables useful for actual edits and mainainersAfterProposedChanges check AuthzGroup realmEdit = authzGroupService.getAuthzGroup(realmId); String maintainRoleString = realmEdit.getMaintainRole(); List participants = collectionToList((Collection) state.getAttribute(STATE_PARTICIPANT_LIST)); // SAK 23029 Test proposed removals/updates; reject all where activeMainainer count would = 0 if all proposed changes were made List<Participant> maintainersAfterProposedChanges = testProposedUpdates(participants, params, maintainRoleString); if (maintainersAfterProposedChanges.size() == 0) { addAlert(state, rb.getFormattedMessage("sitegen.siteinfolist.lastmaintainuseractive", new Object[] { maintainRoleString })); return; } // SAK23029 - proposed changes do not leave site w/o maintainers; proceed with any allowed updates // list of roles being added or removed HashSet<String> roles = new HashSet<String>(); // List used for user auditing List<String[]> userAuditList = new ArrayList<String[]>(); // remove all roles and then add back those that were checked for (int i = 0; i < participants.size(); i++) { String id = null; // added participant Participant participant = (Participant) participants.get(i); id = participant.getUniqname(); if (id != null) { // get the newly assigned role String inputRoleField = "role" + id; String roleId = params.getString(inputRoleField); String oldRoleId = participant.getRole(); boolean roleChange = roleId != null && !roleId.equals(oldRoleId); // get the grant active status boolean activeGrant = true; String activeGrantField = "activeGrant" + id; if (params.getString(activeGrantField) != null) { activeGrant = params.getString(activeGrantField).equalsIgnoreCase("true") ? true : false; } boolean activeGrantChange = roleId != null && (participant.isActive() && !activeGrant || !participant.isActive() && activeGrant); // save any roles changed for permission check if (roleChange) { roles.add(roleId); roles.add(oldRoleId); } // SAK-23257 - display an error message if the new role is in the restricted role list String siteType = s.getType(); List<Role> allowedRoles = SiteParticipantHelper.getAllowedRoles(siteType, getRoles(state)); for (String roleName : roles) { Role r = realmEdit.getRole(roleName); if (!allowedRoles.contains(r)) { addAlert(state, rb.getFormattedMessage("java.roleperm", new Object[] { roleName })); return; } } if (roleChange || activeGrantChange) { boolean fromProvider = !participant.isRemoveable(); if (fromProvider && !roleId.equals(participant.getRole())) { fromProvider = false; } realmEdit.addMember(id, roleId, activeGrant, fromProvider); String currentUserId = (String) state.getAttribute(STATE_CM_CURRENT_USERID); String[] userAuditString = { s.getId(), participant.getEid(), roleId, userAuditService.USER_AUDIT_ACTION_UPDATE, userAuditRegistration.getDatabaseSourceKey(), currentUserId }; userAuditList.add(userAuditString); // construct the event string String userUpdatedString = "uid=" + id; if (roleChange) { userUpdatedString += ";oldRole=" + oldRoleId + ";newRole=" + roleId; } else { userUpdatedString += ";role=" + roleId; } if (activeGrantChange) { userUpdatedString += ";oldActive=" + participant.isActive() + ";newActive=" + activeGrant; } else { userUpdatedString += ";active=" + activeGrant; } userUpdatedString += ";provided=" + fromProvider; // add to the list for all participants that have role changes userUpdated.add(userUpdatedString); } } } // remove selected users if (params.getStrings("selectedUser") != null) { List removals = new ArrayList(Arrays.asList(params.getStrings("selectedUser"))); state.setAttribute(STATE_SELECTED_USER_LIST, removals); for (int i = 0; i < removals.size(); i++) { String rId = (String) removals.get(i); try { User user = UserDirectoryService.getUser(rId); // save role for permission check if (user != null) { String userId = user.getId(); Member userMember = realmEdit.getMember(userId); if (userMember != null) { Role role = userMember.getRole(); if (role != null) { roles.add(role.getId()); } realmEdit.removeMember(userId); usersDeleted.add("uid=" + userId); String currentUserId = (String) state.getAttribute(STATE_CM_CURRENT_USERID); String[] userAuditString = { s.getId(), user.getEid(), role.getId(), userAuditService.USER_AUDIT_ACTION_REMOVE, userAuditRegistration.getDatabaseSourceKey(), currentUserId }; userAuditList.add(userAuditString); } } } catch (UserNotDefinedException e) { M_log.error(this + ".doUpdate_participant: IdUnusedException " + rId + ". ", e); if (("admins".equals(showOrphanedMembers) && SecurityService.isSuperUser()) || ("maintainers".equals(showOrphanedMembers))) { Member userMember = realmEdit.getMember(rId); if (userMember != null) { Role role = userMember.getRole(); if (role != null) { roles.add(role.getId()); } realmEdit.removeMember(rId); } } } } } // if user doesn't have update, don't let them add or remove any role with site.upd in it. if (!authzGroupService.allowUpdate(realmId)) { // see if any changed have site.upd for (String rolename : roles) { Role role = realmEdit.getRole(rolename); if (role != null && role.isAllowed("site.upd")) { addAlert(state, rb.getFormattedMessage("java.roleperm", new Object[] { rolename })); return; } } } authzGroupService.save(realmEdit); // do the audit logging - Doing this in one bulk call to the database will cause the actual audit stamp to be off by maybe 1 second at the most // but seems to be a better solution than call this multiple time for every update if (!userAuditList.isEmpty()) { userAuditRegistration.addToUserAuditing(userAuditList); } // then update all related group realms for the role doUpdate_related_group_participants(s, realmId); // post event about the participant update EventTrackingService.post(EventTrackingService.newEvent(SiteService.SECURE_UPDATE_SITE_MEMBERSHIP, realmEdit.getId(), false)); // check the configuration setting, whether logging membership // change at individual level is allowed if (ServerConfigurationService.getBoolean(SiteHelper.WSETUP_TRACK_USER_MEMBERSHIP_CHANGE, false)) { // event for each individual update for (String userChangedRole : userUpdated) { EventTrackingService.post(EventTrackingService.newEvent( org.sakaiproject.site.api.SiteService.EVENT_USER_SITE_MEMBERSHIP_UPDATE, userChangedRole, true)); } // event for each individual remove for (String userDeleted : usersDeleted) { EventTrackingService.post(EventTrackingService.newEvent( org.sakaiproject.site.api.SiteService.EVENT_USER_SITE_MEMBERSHIP_REMOVE, userDeleted, true)); } } } catch (GroupNotDefinedException e) { addAlert(state, rb.getString("java.problem2")); M_log.error( this + ".doUpdate_participant: IdUnusedException " + s.getTitle() + "(" + realmId + "). ", e); } catch (AuthzPermissionException e) { addAlert(state, rb.getString("java.changeroles")); M_log.error( this + ".doUpdate_participant: PermissionException " + s.getTitle() + "(" + realmId + "). ", e); } } } // doUpdate_participant /** * update realted group realm setting according to parent site realm changes * @param s * @param realmId */ private void doUpdate_related_group_participants(Site s, String realmId) { Collection groups = s.getGroups(); boolean trackIndividualChange = ServerConfigurationService .getBoolean(SiteHelper.WSETUP_TRACK_USER_MEMBERSHIP_CHANGE, false); if (groups != null) { try { for (Iterator iGroups = groups.iterator(); iGroups.hasNext();) { Group g = (Group) iGroups.next(); if (g != null) { try { Set gMembers = g.getMembers(); for (Iterator iGMembers = gMembers.iterator(); iGMembers.hasNext();) { Member gMember = (Member) iGMembers.next(); String gMemberId = gMember.getUserId(); Member siteMember = s.getMember(gMemberId); if (siteMember == null) { // user has been removed from the site g.removeMember(gMemberId); } else { // check for Site Info-managed groups: don't change roles for other groups (e.g. section-managed groups) String gProp = g.getProperties().getProperty(g.GROUP_PROP_WSETUP_CREATED); // if there is a difference between the role setting, remove the entry from group and add it back with correct role, all are marked "not provided" Role groupRole = g.getUserRole(gMemberId); Role siteRole = siteMember.getRole(); if (gProp != null && gProp.equals(Boolean.TRUE.toString()) && groupRole != null && siteRole != null && !groupRole.equals(siteRole)) { if (g.getRole(siteRole.getId()) == null) { // in case there is no matching role as that in the site, create such role and add it to the user g.addRole(siteRole.getId(), siteRole); } g.removeMember(gMemberId); g.addMember(gMemberId, siteRole.getId(), siteMember.isActive(), false); // track the group membership change at individual level if (trackIndividualChange) { // an event for each individual member role change EventTrackingService.post(EventTrackingService.newEvent( org.sakaiproject.site.api.SiteService.EVENT_USER_GROUP_MEMBERSHIP_UPDATE, "uid=" + gMemberId + ";groupId=" + g.getId() + ";oldRole=" + groupRole + ";newRole=" + siteRole + ";active=" + siteMember.isActive() + ";provided=false", true/*update event*/)); } } } } // post event about the participant update EventTrackingService.post(EventTrackingService .newEvent(SiteService.SECURE_UPDATE_GROUP_MEMBERSHIP, g.getId(), true)); } catch (Exception ee) { M_log.error( this + ".doUpdate_related_group_participants: " + ee.getMessage() + g.getId(), ee); } } } // commit, save the site SiteService.save(s); } catch (Exception e) { M_log.error(this + ".doUpdate_related_group_participants: " + e.getMessage() + s.getId(), e); } } } /** * doUpdate_site_access * */ public void doUpdate_site_access(RunData data) { if (!"POST".equals(data.getRequest().getMethod())) { M_log.warn("Ignoring non-POST request to update site access."); return; } SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); Site sEdit = getStateSite(state); ParameterParser params = data.getParameters(); // get all form inputs readInputAndUpdateStateVariable(state, params, "publishunpublish", STATE_SITE_ACCESS_PUBLISH, true); readInputAndUpdateStateVariable(state, params, "include", STATE_SITE_ACCESS_INCLUDE, true); readInputAndUpdateStateVariable(state, params, "joinable", STATE_JOINABLE, true); readInputAndUpdateStateVariable(state, params, "joinerRole", STATE_JOINERROLE, false); // bjones86 - SAK-24423 - get all joinable site settings from the form input JoinableSiteSettings.getAllFormInputs(state, params); boolean publishUnpublish = state.getAttribute(STATE_SITE_ACCESS_PUBLISH) != null ? ((Boolean) state.getAttribute(STATE_SITE_ACCESS_PUBLISH)).booleanValue() : false; // the site publish status before update boolean currentSitePublished = sEdit != null ? sEdit.isPublished() : false; boolean include = state.getAttribute(STATE_SITE_ACCESS_INCLUDE) != null ? ((Boolean) state.getAttribute(STATE_SITE_ACCESS_INCLUDE)).booleanValue() : false; if (sEdit != null) { // editing existing site // publish site or not sEdit.setPublished(publishUnpublish); // site public choice List publicChangeableSiteTypes = (List) state.getAttribute(STATE_PUBLIC_CHANGEABLE_SITE_TYPES); if (publicChangeableSiteTypes != null && sEdit.getType() != null && !publicChangeableSiteTypes.contains(sEdit.getType())) { // set pubview to true for those site types which pubview change is not allowed sEdit.setPubView(true); } else { // set pubview according to UI selection sEdit.setPubView(include); } doUpdate_site_access_joinable(data, state, params, sEdit); Map<String, AdditionalRole> additionalRoles = getAdditionalAccess(sEdit); for (String role : additionalRoles.keySet()) { boolean userChoice = params.getBoolean("role" + role); AdditionalRole additionalRole = additionalRoles.get(role); if (additionalRole.editable) { if (additionalRole.granted != userChoice) { updateAdditionalRole(state, sEdit, role, userChoice); } } } if (state.getAttribute(STATE_MESSAGE) == null) { commitSite(sEdit); if (currentSitePublished && !publishUnpublish) { // unpublishing a published site EventTrackingService.post(EventTrackingService.newEvent(SiteService.EVENT_SITE_UNPUBLISH, sEdit.getReference(), true)); } else if (!currentSitePublished && publishUnpublish) { // publishing a published site EventTrackingService.post(EventTrackingService.newEvent(SiteService.EVENT_SITE_PUBLISH, sEdit.getReference(), true)); } state.setAttribute(STATE_TEMPLATE_INDEX, "12"); // TODO: hard coding this frame id is fragile, portal dependent, // and needs to be fixed -ggolden // schedulePeerFrameRefresh("sitenav"); scheduleTopRefresh(); state.removeAttribute(STATE_JOINABLE); state.removeAttribute(STATE_JOINERROLE); // bjones86 - SAK-24423 - remove joinable site settings from the state JoinableSiteSettings.removeJoinableSiteSettingsFromState(state); } } else { // adding new site if (state.getAttribute(STATE_SITE_INFO) != null) { SiteInfo siteInfo = (SiteInfo) state.getAttribute(STATE_SITE_INFO); siteInfo.published = publishUnpublish; // site public choice siteInfo.include = include; // joinable site or not boolean joinable = state.getAttribute(STATE_JOINABLE) != null ? ((Boolean) state.getAttribute(STATE_JOINABLE)).booleanValue() : null; // bjones86 - SAK-24423 - update site info for joinable site settings JoinableSiteSettings.updateSiteInfoFromStateOnSiteUpdate(state, siteInfo, joinable); if (joinable) { siteInfo.joinable = true; String joinerRole = state.getAttribute(STATE_JOINERROLE) != null ? (String) state.getAttribute(STATE_JOINERROLE) : null; if (joinerRole != null) { siteInfo.joinerRole = joinerRole; } else { siteInfo.joinerRole = null; addAlert(state, rb.getString("java.joinsite") + " "); } } else { siteInfo.joinable = false; siteInfo.joinerRole = null; } // Stash the list of roles to add to the site. siteInfo.additionalRoles = new HashSet<String>(); Map<String, AdditionalRole> additionalRoles = loadAdditionalRoles(); for (String role : additionalRoles.keySet()) { boolean userChoice = params.getBoolean("role" + role); if (userChoice) { siteInfo.additionalRoles.add(role); } } state.setAttribute(STATE_SITE_INFO, siteInfo); } //if creating a site from an archive, go to that template //otherwise go to confirm page if (state.getAttribute(STATE_MESSAGE) == null) { if (state.getAttribute(STATE_CREATE_FROM_ARCHIVE) == Boolean.TRUE) { state.setAttribute(STATE_TEMPLATE_INDEX, "62"); } else { state.setAttribute(STATE_TEMPLATE_INDEX, "10"); } } } } // doUpdate_site_access private void updateAdditionalRole(SessionState state, Site site, String roleId, boolean add) { try { if (add) { AuthzGroup templateGroup = authzGroupService.getAuthzGroup("!site.roles"); Role role = templateGroup.getRole(roleId); if (role == null) { role = templateGroup.getRole(".default"); } if (site.getRole(roleId) == null) { try { site.addRole(roleId, role); } catch (RoleAlreadyDefinedException e) { addAlert(state, "java.authroleexists"); } } else { M_log.warn("Attempting to add a role (" + roleId + ") that already exists in site: " + site.getId()); } } else { if (site.getRole(roleId) != null) { site.removeRole(roleId); } else { M_log.warn("Attempting to remove a role (" + roleId + ") that isn't defined in site: " + site.getId()); } } } catch (GroupNotDefinedException gnde) { addAlert(state, rb.getString("java.rolenotfound")); } } private void addAuthAnonRoles(SessionState state, Site site, boolean auth, boolean anon) { try { AuthzGroup templateGroup = authzGroupService.getAuthzGroup("!site.roles"); if (auth) { if (site.getRole(".anon") != null) { site.removeRole(".anon"); } if (site.getRole(".auth") == null) { try { site.addRole(".auth", templateGroup.getRole(".auth")); } catch (RoleAlreadyDefinedException e) { addAlert(state, "java.authroleexists"); } } } else if (anon) { if (site.getRole(".auth") != null) { site.removeRole(".auth"); } if (site.getRole(".anon") == null) { try { site.addRole(".anon", templateGroup.getRole(".anon")); } catch (RoleAlreadyDefinedException e) { addAlert(state, "java.anonroleexists"); } } } else { if (site.getRole(".anon") != null) { site.removeRole(".anon"); } if (site.getRole(".auth") != null) { site.removeRole(".auth"); } } } catch (GroupNotDefinedException gnde) { addAlert(state, rb.getString("java.rolenotfound")); } } private void readInputAndUpdateStateVariable(SessionState state, ParameterParser params, String paramName, String stateAttributeName, boolean isBoolean) { String paramValue = StringUtils.trimToNull(params.getString(paramName)); if (paramValue != null) { if (isBoolean) { state.setAttribute(stateAttributeName, Boolean.valueOf(paramValue)); } else { state.setAttribute(stateAttributeName, paramValue); } } else { state.removeAttribute(stateAttributeName); } } /** * Apply requested changes to a site's joinability. Only relevant for * site edits, not new site creation. * * <p>Not intended for direct execution from a Velocity-rendered form * submit.</p> * * <p>Originally extracted from {@link #doUpdate_site_access(RunData)} to * increase testability when adding special handling for an unspecified * joinability parameter. The <code>sEdit</code> param is passed in * to avoid repeated hits to the <code>SiteService</code> from * {@link #getStateSite(SessionState)}. (It's called <code>sEdit</code> to * reduce the scope of the refactoring diff just slightly.) <code>state</code> * is passed in to avoid more proliferation of <code>RunData</code> * downcasts.</p> * * @see #CONVERT_NULL_JOINABLE_TO_UNJOINABLE * @param data request context -- must not be <code>null</code> * @param state session state -- must not be <code>null</code> * @param params request parameter facade -- must not be <code>null</code> * @param sEdit site to be edited -- must not be <code>null</code> */ void doUpdate_site_access_joinable(RunData data, SessionState state, ParameterParser params, Site sEdit) { boolean joinable = state.getAttribute(STATE_JOINABLE) != null ? ((Boolean) state.getAttribute(STATE_JOINABLE)).booleanValue() : null; if (!sEdit.isPublished()) { // reset joinable role if the site is not published sEdit.setJoinable(false); sEdit.setJoinerRole(null); } else if (joinable) { sEdit.setJoinable(true); String joinerRole = state.getAttribute(STATE_JOINERROLE) != null ? (String) state.getAttribute(STATE_JOINERROLE) : null; if (joinerRole != null) { sEdit.setJoinerRole(joinerRole); } else { addAlert(state, rb.getString("java.joinsite") + " "); } // Handle invalid joinable site settings try { // Update site properties for joinable site settings JoinableSiteSettings.updateSitePropertiesFromStateOnSiteUpdate(sEdit.getPropertiesEdit(), state); } catch (InvalidJoinableSiteSettingsException invalidSettingsException) { addAlert(state, invalidSettingsException.getFormattedMessage(rb)); } } else if (!joinable || (!joinable && ServerConfigurationService.getBoolean(CONVERT_NULL_JOINABLE_TO_UNJOINABLE, true))) { sEdit.setJoinable(false); sEdit.setJoinerRole(null); } // else just leave joinability alone } /** * /* Actions for vm templates under the "chef_site" root. This method is * called by doContinue. Each template has a hidden field with the value of * template-index that becomes the value of index for the switch statement * here. Some cases not implemented. */ private void actionForTemplate(String direction, int index, ParameterParser params, final SessionState state, RunData data) { // Continue - make any permanent changes, Back - keep any data entered // on the form boolean forward = "continue".equals(direction) ? true : false; SiteInfo siteInfo = new SiteInfo(); // SAK-16600 change to new template for tool editing if (index == 3) { index = 4; } switch (index) { case 0: /* * actionForTemplate chef_site-list.vm * */ break; case 1: /* * actionForTemplate chef_site-type.vm * */ break; case 4: /* * actionForTemplate chef_site-editFeatures.vm * actionForTemplate chef_site-editToolGroupFeatures.vm * */ if (forward) { // editing existing site or creating a new one? Site site = getStateSite(state); getFeatures(params, state, site == null ? "18" : "15"); } break; case 8: /* * actionForTemplate chef_site-siteDeleteConfirm.vm * */ break; case 10: /* * actionForTemplate chef_site-newSiteConfirm.vm * */ if (!forward) { } break; case 12: /* * actionForTemplate chef_site_siteInfo-list.vm * */ break; case 13: /* * actionForTemplate chef_site_siteInfo-editInfo.vm * */ if (forward) { if (getStateSite(state) == null) { // alerts after clicking Continue but not Back if (!forward) { // removing previously selected template site state.removeAttribute(STATE_TEMPLATE_SITE); } updateSiteAttributes(state); } updateSiteInfo(params, state); } break; case 14: /* * actionForTemplate chef_site_siteInfo-editInfoConfirm.vm * */ break; case 15: /* * actionForTemplate chef_site_siteInfo-addRemoveFeatureConfirm.vm * */ break; case 18: /* * actionForTemplate chef_siteInfo-editAccess.vm * */ if (!forward) { } break; case 24: /* * actionForTemplate * chef_site-siteInfo-editAccess-globalAccess-confirm.vm * */ break; case 26: /* * actionForTemplate chef_site-modifyENW.vm * */ updateSelectedToolList(state, params, true); break; case 27: /* * actionForTemplate chef_site-importSites.vm * * This is called after the tools have been selected on the import page (merge) and the finish button is clicked * and is also called in the new site workflow when importing from an existing site */ if (forward) { Site existingSite = getStateSite(state); if (existingSite != null) { // revising a existing site's tool if (select_import_tools(params, state)) { String threadName = "SiteImportThread" + existingSite.getId(); boolean found = false; //check all running threads for our named thread //this isn't cluster safe, but this check it more targeted towards //a single user re-importing multiple times during a slow import (which would be on the same server) for (Thread t : Thread.getAllStackTraces().keySet()) { if (threadName.equals(t.getName())) { found = true; break; } } if (found) { //an existing thread is running for this site import, throw warning addAlert(state, rb.getString("java.import.existing")); } else { // list of tools that were selected for import final Hashtable importTools = (Hashtable) state.getAttribute(STATE_IMPORT_SITE_TOOL); //list of existing tools in the destination site final List existingTools = originalToolIds( (List<String>) state.getAttribute(STATE_TOOL_REGISTRATION_SELECTED_LIST), state); final String userEmail = UserDirectoryService.getCurrentUser().getEmail(); final Session session = SessionManager.getCurrentSession(); final ToolSession toolSession = SessionManager.getCurrentToolSession(); final String siteId = existingSite.getId(); Thread siteImportThread = new Thread() { public void run() { Site existingSite; try { existingSite = SiteService.getSite(siteId); SessionManager.setCurrentSession(session); SessionManager.setCurrentToolSession(toolSession); EventTrackingService.post( EventTrackingService.newEvent(SiteService.EVENT_SITE_IMPORT_START, existingSite.getReference(), false)); importToolIntoSite(existingTools, importTools, existingSite); if (ServerConfigurationService.getBoolean(SAK_PROP_IMPORT_NOTIFICATION, true)) { userNotificationProvider.notifySiteImportCompleted(userEmail, existingSite.getId(), existingSite.getTitle()); } EventTrackingService.post( EventTrackingService.newEvent(SiteService.EVENT_SITE_IMPORT_END, existingSite.getReference(), false)); } catch (IdUnusedException e) { M_log.error(e.getMessage(), e); } } }; siteImportThread.setName(threadName); siteImportThread.start(); state.setAttribute(IMPORT_QUEUED, rb.get("importQueued")); state.removeAttribute(STATE_IMPORT_SITE_TOOL); state.removeAttribute(STATE_IMPORT_SITES); } } else { // show alert and remain in current page addAlert(state, rb.getString("java.toimporttool")); } } else { // new site select_import_tools(params, state); } } else { // read form input about import tools select_import_tools(params, state); } break; case 60: /* * actionForTemplate chef_site-importSitesMigrate.vm * * This is called after the tools have been selected on the import page (replace) and the finish button is clicked * */ if (forward) { Site existingSite = getStateSite(state); if (existingSite != null) { // revising a existing site's tool if (select_import_tools(params, state)) { String threadName = "SiteImportThread" + existingSite.getId(); boolean found = false; //check all running threads for our named thread //this isn't cluster safe, but this check it more targeted towards //a single user re-importing multiple times during a slow import (which would be on the same server) for (Thread t : Thread.getAllStackTraces().keySet()) { if (threadName.equals(t.getName())) { found = true; break; } } if (found) { //an existing thread is running for this site import, throw warning addAlert(state, rb.getString("java.import.existing")); } else { // list of tools that were selected for import final Hashtable importTools = (Hashtable) state.getAttribute(STATE_IMPORT_SITE_TOOL); //list of existing tools in the destination site final List existingTools = originalToolIds( (List<String>) state.getAttribute(STATE_TOOL_REGISTRATION_SELECTED_LIST), state); final String userEmail = UserDirectoryService.getCurrentUser().getEmail(); final Session session = SessionManager.getCurrentSession(); final ToolSession toolSession = SessionManager.getCurrentToolSession(); final String siteId = existingSite.getId(); Thread siteImportThread = new Thread() { public void run() { Site existingSite; try { existingSite = SiteService.getSite(siteId); SessionManager.setCurrentSession(session); SessionManager.setCurrentToolSession(toolSession); EventTrackingService.post( EventTrackingService.newEvent(SiteService.EVENT_SITE_IMPORT_START, existingSite.getReference(), false)); // Remove all old contents before importing contents from new site importToolIntoSiteMigrate(existingTools, importTools, existingSite); if (ServerConfigurationService.getBoolean(SAK_PROP_IMPORT_NOTIFICATION, true)) { userNotificationProvider.notifySiteImportCompleted(userEmail, existingSite.getId(), existingSite.getTitle()); } EventTrackingService.post( EventTrackingService.newEvent(SiteService.EVENT_SITE_IMPORT_END, existingSite.getReference(), false)); } catch (IdUnusedException e) { M_log.error(e.getMessage(), e); } } }; siteImportThread.setName(threadName); siteImportThread.start(); state.setAttribute(IMPORT_QUEUED, rb.get("importQueued")); state.removeAttribute(STATE_IMPORT_SITE_TOOL); state.removeAttribute(STATE_IMPORT_SITES); } } else { // show alert and remain in current page addAlert(state, rb.getString("java.toimporttool")); } } else { // new site select_import_tools(params, state); } } else { // read form input about import tools select_import_tools(params, state); } break; case 28: /* * actionForTemplate chef_siteinfo-import.vm * * This is called after the sites to import from have been selected on the import page and the next button is clicked * */ if (forward) { if (params.getStrings("importSites") == null) { addAlert(state, rb.getString("java.toimport") + " "); state.removeAttribute(STATE_IMPORT_SITES); } else { List importSites = new ArrayList(Arrays.asList(params.getStrings("importSites"))); Hashtable sites = new Hashtable(); for (index = 0; index < importSites.size(); index++) { try { Site s = SiteService.getSite((String) importSites.get(index)); sites.put(s, new Vector()); } catch (IdUnusedException e) { } } state.setAttribute(STATE_IMPORT_SITES, sites); } } break; case 58: /* * actionForTemplate chef_siteinfo-importSelection.vm * */ break; case 59: /* * actionForTemplate chef_siteinfo-import.vm * */ if (forward) { if (params.getStrings("importSites") == null) { addAlert(state, rb.getString("java.toimport") + " "); state.removeAttribute(STATE_IMPORT_SITES); } else { List importSites = new ArrayList(Arrays.asList(params.getStrings("importSites"))); Hashtable sites = new Hashtable(); for (index = 0; index < importSites.size(); index++) { try { Site s = SiteService.getSite((String) importSites.get(index)); sites.put(s, new Vector()); } catch (IdUnusedException e) { } } state.setAttribute(STATE_IMPORT_SITES, sites); } } break; case 29: /* * actionForTemplate chef_siteinfo-duplicate.vm * */ if (forward) { if (state.getAttribute(SITE_DUPLICATED) == null) { if (StringUtils.trimToNull(params.getString("title")) == null) { addAlert(state, rb.getString("java.dupli") + " "); } else { String title = params.getString("title"); state.setAttribute(SITE_DUPLICATED_NAME, title); String newSiteId = IdManager.createUuid(); try { String oldSiteId = (String) state.getAttribute(STATE_SITE_INSTANCE_ID); // Retrieve the source site reference to be used in the EventTrackingService // notification of the start/end of a site duplication. String sourceSiteRef = null; try { Site sourceSite = SiteService.getSite(oldSiteId); sourceSiteRef = sourceSite.getReference(); } catch (IdUnusedException e) { M_log.warn( this + ".actionForTemplate; case29: invalid source siteId: " + oldSiteId); return; } // SAK-20797 long oldSiteQuota = this.getSiteSpecificQuota(oldSiteId); Site site = SiteService.addSite(newSiteId, getStateSite(state)); // An event for starting the "duplicate site" action EventTrackingService .post(EventTrackingService.newEvent(SiteService.EVENT_SITE_DUPLICATE_START, sourceSiteRef, site.getId(), false, NotificationService.NOTI_OPTIONAL)); // get the new site icon url if (site.getIconUrl() != null) { site.setIconUrl(transferSiteResource(oldSiteId, newSiteId, site.getIconUrl())); } // set title site.setTitle(title); // SAK-20797 alter quota if required boolean duplicateQuota = params.getString("dupequota") != null ? params.getBoolean("dupequota") : false; if (duplicateQuota == true) { if (oldSiteQuota > 0) { M_log.info("Saving quota"); try { String collId = m_contentHostingService.getSiteCollection(site.getId()); ContentCollectionEdit col = m_contentHostingService.editCollection(collId); ResourcePropertiesEdit resourceProperties = col.getPropertiesEdit(); resourceProperties.addProperty( ResourceProperties.PROP_COLLECTION_BODY_QUOTA, new Long(oldSiteQuota).toString()); m_contentHostingService.commitCollection(col); } catch (Exception ignore) { M_log.warn("saveQuota: unable to duplicate site-specific quota for site : " + site.getId() + " : " + ignore); } } } try { SiteService.save(site); // import tool content importToolContent(oldSiteId, site, false); String siteType = site.getType(); if (SiteTypeUtil.isCourseSite(siteType)) { // for course site, need to // read in the input for // term information String termId = StringUtils.trimToNull(params.getString("selectTerm")); if (termId != null) { AcademicSession term = cms.getAcademicSession(termId); if (term != null) { ResourcePropertiesEdit rp = site.getPropertiesEdit(); rp.addProperty(Site.PROP_SITE_TERM, term.getTitle()); rp.addProperty(Site.PROP_SITE_TERM_EID, term.getEid()); } else { M_log.warn("termId=" + termId + " not found"); } } } // save again SiteService.save(site); String realm = SiteService.siteReference(site.getId()); try { AuthzGroup realmEdit = authzGroupService.getAuthzGroup(realm); if (SiteTypeUtil.isCourseSite(siteType)) { // also remove the provider id attribute if any realmEdit.setProviderGroupId(null); } // add current user as the maintainer realmEdit.addMember(UserDirectoryService.getCurrentUser().getId(), site.getMaintainRole(), true, false); authzGroupService.save(realmEdit); } catch (GroupNotDefinedException e) { M_log.error(this + ".actionForTemplate chef_siteinfo-duplicate: IdUnusedException, not found, or not an AuthzGroup object " + realm, e); addAlert(state, rb.getString("java.realm")); } catch (AuthzPermissionException e) { addAlert(state, this + rb.getString("java.notaccess")); M_log.error(this + ".actionForTemplate chef_siteinfo-duplicate: " + rb.getString("java.notaccess"), e); } } catch (IdUnusedException e) { M_log.warn(this + " actionForTemplate chef_siteinfo-duplicate:: IdUnusedException when saving " + newSiteId); } catch (PermissionException e) { M_log.warn(this + " actionForTemplate chef_siteinfo-duplicate:: PermissionException when saving " + newSiteId); } // TODO: hard coding this frame id // is fragile, portal dependent, and // needs to be fixed -ggolden // schedulePeerFrameRefresh("sitenav"); scheduleTopRefresh(); // send site notification sendSiteNotification(state, site, null); state.setAttribute(SITE_DUPLICATED, Boolean.TRUE); // An event for ending the "duplicate site" action EventTrackingService .post(EventTrackingService.newEvent(SiteService.EVENT_SITE_DUPLICATE_END, sourceSiteRef, site.getId(), false, NotificationService.NOTI_OPTIONAL)); } catch (IdInvalidException e) { addAlert(state, rb.getString("java.siteinval")); M_log.error(this + ".actionForTemplate chef_siteinfo-duplicate: " + rb.getString("java.siteinval") + " site id = " + newSiteId, e); } catch (IdUsedException e) { addAlert(state, rb.getString("java.sitebeenused")); M_log.error(this + ".actionForTemplate chef_siteinfo-duplicate: " + rb.getString("java.sitebeenused") + " site id = " + newSiteId, e); } catch (PermissionException e) { addAlert(state, rb.getString("java.allowcreate")); M_log.error(this + ".actionForTemplate chef_siteinfo-duplicate: " + rb.getString("java.allowcreate") + " site id = " + newSiteId, e); } } } if (state.getAttribute(STATE_MESSAGE) == null) { // site duplication confirmed state.removeAttribute(SITE_DUPLICATED); state.removeAttribute(SITE_DUPLICATED_NAME); // return to the list view state.setAttribute(STATE_TEMPLATE_INDEX, "12"); } } break; case 33: break; case 36: /* * actionForTemplate chef_site-newSiteCourse.vm */ if (forward) { List providerChosenList = new Vector(); List providerDescriptionChosenList = new Vector(); if (params.getStrings("providerCourseAdd") == null) { state.removeAttribute(STATE_ADD_CLASS_PROVIDER_CHOSEN); state.removeAttribute(STATE_ADD_CLASS_PROVIDER_DESCRIPTION_CHOSEN); if (params.getString("manualAdds") == null) { addAlert(state, rb.getString("java.manual") + " "); } } if (state.getAttribute(STATE_MESSAGE) == null) { // The list of courses selected from provider listing if (params.getStrings("providerCourseAdd") != null) { providerChosenList = new ArrayList(Arrays.asList(params.getStrings("providerCourseAdd"))); // list of // description choices if (params.getStrings("providerCourseAddDescription") != null) { providerDescriptionChosenList = new ArrayList( Arrays.asList(params.getStrings("providerCourseAddDescription"))); // list of state.setAttribute(STATE_ADD_CLASS_PROVIDER_DESCRIPTION_CHOSEN, providerDescriptionChosenList); } // course // ids String userId = (String) state.getAttribute(STATE_INSTRUCTOR_SELECTED); String currentUserId = (String) state.getAttribute(STATE_CM_CURRENT_USERID); if (userId == null || (userId != null && userId.equals(currentUserId))) { state.setAttribute(STATE_ADD_CLASS_PROVIDER_CHOSEN, providerChosenList); state.removeAttribute(STATE_CM_AUTHORIZER_SECTIONS); state.removeAttribute(FORM_ADDITIONAL); state.removeAttribute(STATE_CM_AUTHORIZER_LIST); } else { // STATE_CM_AUTHORIZER_SECTIONS are SectionObject, // so need to prepare it // also in this page, u can pick either section from // current user OR // sections from another users but not both. - // daisy's note 1 for now // till we are ready to add more complexity List sectionObjectList = prepareSectionObject(providerChosenList, userId); state.setAttribute(STATE_CM_AUTHORIZER_SECTIONS, sectionObjectList); state.removeAttribute(STATE_ADD_CLASS_PROVIDER_CHOSEN); // set special instruction & we will keep // STATE_CM_AUTHORIZER_LIST String additional = StringUtils.trimToEmpty(params.getString("additional")); state.setAttribute(FORM_ADDITIONAL, additional); } } collectNewSiteInfo(state, params, providerChosenList); String find_course = params.getString("find_course"); if (state.getAttribute(STATE_TEMPLATE_SITE) != null && (find_course == null || !"true".equals(find_course))) { // creating based on template doFinish(data); } } } break; case 38: break; case 39: break; case 42: /* * actionForTemplate chef_site-type-confirm.vm * */ break; case 43: /* * actionForTemplate chef_site-editClass.vm * */ if (forward) { if (params.getStrings("providerClassDeletes") == null && params.getStrings("manualClassDeletes") == null && params.getStrings("cmRequestedClassDeletes") == null && !"back".equals(direction)) { addAlert(state, rb.getString("java.classes")); } if (params.getStrings("providerClassDeletes") != null) { // build the deletions list List providerCourseList = (List) state.getAttribute(SITE_PROVIDER_COURSE_LIST); List providerCourseDeleteList = new ArrayList( Arrays.asList(params.getStrings("providerClassDeletes"))); for (ListIterator i = providerCourseDeleteList.listIterator(); i.hasNext();) { providerCourseList.remove((String) i.next()); } //Track provider deletes, seems like the only place to do it. If a confirmation is ever added somewhere, don't do this. trackRosterChanges(org.sakaiproject.site.api.SiteService.EVENT_SITE_ROSTER_REMOVE, providerCourseDeleteList); state.setAttribute(SITE_PROVIDER_COURSE_LIST, providerCourseList); } if (params.getStrings("manualClassDeletes") != null) { // build the deletions list List manualCourseList = (List) state.getAttribute(SITE_MANUAL_COURSE_LIST); List manualCourseDeleteList = new ArrayList( Arrays.asList(params.getStrings("manualClassDeletes"))); for (ListIterator i = manualCourseDeleteList.listIterator(); i.hasNext();) { manualCourseList.remove((String) i.next()); } state.setAttribute(SITE_MANUAL_COURSE_LIST, manualCourseList); } if (params.getStrings("cmRequestedClassDeletes") != null) { // build the deletions list List<SectionObject> cmRequestedCourseList = (List) state .getAttribute(STATE_CM_REQUESTED_SECTIONS); List<String> cmRequestedCourseDeleteList = new ArrayList( Arrays.asList(params.getStrings("cmRequestedClassDeletes"))); for (ListIterator i = cmRequestedCourseDeleteList.listIterator(); i.hasNext();) { String sectionId = (String) i.next(); try { SectionObject so = new SectionObject(cms.getSection(sectionId)); SectionObject soFound = null; for (Iterator j = cmRequestedCourseList.iterator(); soFound == null && j.hasNext();) { SectionObject k = (SectionObject) j.next(); if (k.eid.equals(sectionId)) { soFound = k; } } if (soFound != null) cmRequestedCourseList.remove(soFound); } catch (IdNotFoundException e) { M_log.warn("actionForTemplate 43 editClass: Cannot find section " + sectionId); } } state.setAttribute(STATE_CM_REQUESTED_SECTIONS, cmRequestedCourseList); } updateCourseClasses(state, new Vector(), new Vector()); } break; case 44: if (forward) { AcademicSession a = (AcademicSession) state.getAttribute(STATE_TERM_SELECTED); Site site = getStateSite(state); ResourcePropertiesEdit pEdit = site.getPropertiesEdit(); // update the course site property and realm based on the selection updateCourseSiteSections(state, site.getId(), pEdit, a); try { SiteService.save(site); } catch (Exception e) { M_log.error(this + ".actionForTemplate chef_siteinfo-addCourseConfirm: " + e.getMessage() + site.getId(), e); } removeAddClassContext(state); } break; case 54: if (forward) { // store answers to site setup questions if (getAnswersToSetupQuestions(params, state)) { state.setAttribute(STATE_TEMPLATE_INDEX, state.getAttribute(STATE_SITE_SETUP_QUESTION_NEXT_TEMPLATE)); } } break; case 61: // import users if (forward) { if (params.getStrings("importSites") == null) { addAlert(state, rb.getString("java.toimport") + " "); } else { importSitesUsers(params, state); } } break; } }// actionFor Template /** * * @param action * @param providers */ private void trackRosterChanges(String event, List<String> rosters) { if (ServerConfigurationService.getBoolean(SiteHelper.WSETUP_TRACK_ROSTER_CHANGE, false)) { // event for each individual update if (rosters != null) { for (String roster : rosters) { EventTrackingService.post(EventTrackingService.newEvent(event, "roster=" + roster, true)); } } } } /** * import not-provided users from selected sites * @param params */ private void importSitesUsers(ParameterParser params, SessionState state) { // the target site Site site = getStateSite(state); try { // the target realm AuthzGroup realm = authzGroupService.getAuthzGroup(SiteService.siteReference(site.getId())); List importSites = new ArrayList(Arrays.asList(params.getStrings("importSites"))); for (int i = 0; i < importSites.size(); i++) { String fromSiteId = (String) importSites.get(i); try { Site fromSite = SiteService.getSite(fromSiteId); // get realm information String fromRealmId = SiteService.siteReference(fromSite.getId()); AuthzGroup fromRealm = authzGroupService.getAuthzGroup(fromRealmId); // get all users in the from site Set fromUsers = fromRealm.getUsers(); for (Iterator iFromUsers = fromUsers.iterator(); iFromUsers.hasNext();) { String fromUserId = (String) iFromUsers.next(); Member fromMember = fromRealm.getMember(fromUserId); if (!fromMember.isProvided()) { // add user realm.addMember(fromUserId, fromMember.getRole().getId(), fromMember.isActive(), false); } } } catch (GroupNotDefinedException e) { M_log.error(this + ".importSitesUsers: GroupNotDefinedException, " + fromSiteId + " not found, or not an AuthzGroup object", e); addAlert(state, rb.getString("java.cannotedit")); } catch (IdUnusedException e) { M_log.error(this + ".importSitesUsers: IdUnusedException, " + fromSiteId + " not found, or not an AuthzGroup object", e); } } // post event about the realm participant update EventTrackingService.post( EventTrackingService.newEvent(SiteService.SECURE_UPDATE_SITE_MEMBERSHIP, realm.getId(), false)); // save realm authzGroupService.save(realm); } catch (GroupNotDefinedException e) { M_log.error(this + ".importSitesUsers: IdUnusedException, " + site.getTitle() + "(" + site.getId() + ") not found, or not an AuthzGroup object", e); addAlert(state, rb.getString("java.cannotedit")); } catch (AuthzPermissionException e) { M_log.error(this + ".importSitesUsers: PermissionException, user does not have permission to edit AuthzGroup object " + site.getTitle() + "(" + site.getId() + "). ", e); addAlert(state, rb.getString("java.notaccess")); } } /** * This is used to update exsiting site attributes with encoded site id in it. A new resource item is added to new site when needed * * @param oSiteId * @param nSiteId * @param siteAttribute * @return the new migrated resource url */ private String transferSiteResource(String oSiteId, String nSiteId, String siteAttribute) { String rv = ""; String access = ServerConfigurationService.getAccessUrl(); if (siteAttribute != null && siteAttribute.indexOf(oSiteId) != -1 && access != null) { Reference ref = null; try { URI accessUrl = new URI(access); URI url = new URI(siteAttribute); String path = url.getPath(); String accessPath = accessUrl.getPath(); // stripe out the access url, get the relative form of "url" String contentRef = path.replaceAll(accessPath, ""); ref = EntityManager.newReference(contentRef); ContentResource resource = m_contentHostingService.getResource(ref.getId()); // the new resource ContentResource nResource = null; String nResourceId = resource.getId().replaceAll(oSiteId, nSiteId); try { nResource = m_contentHostingService.getResource(nResourceId); } catch (Exception n2Exception) { M_log.warn(this + ":transferSiteResource: cannot find resource with id=" + nResource + " copying it from the original resource " + n2Exception.getMessage()); // copy the resource then try { nResourceId = m_contentHostingService.copy(resource.getId(), nResourceId); nResource = m_contentHostingService.getResource(nResourceId); } catch (Exception n3Exception) { M_log.warn(this + ":transferSiteResource: something happened copying the resource with id=" + resource.getId() + " " + n3Exception.getMessage()); } } // get the new resource url rv = nResource != null ? nResource.getUrl(false) : ""; } catch (URISyntaxException use) { M_log.warn("Couldn't update site resource: " + siteAttribute + " " + use.getMessage()); } catch (Exception refException) { M_log.warn(this + ":transferSiteResource: cannot find resource with ref=" + ref.getReference() + " " + refException.getMessage()); } } return rv; } /** * copy tool content from old site * @param oSiteId source (old) site id * @param site destination site * @param bypassSecurity use SecurityAdvisor if true */ private void importToolContent(String oSiteId, Site site, boolean bypassSecurity) { String nSiteId = site.getId(); // import tool content if (bypassSecurity) { // importing from template, bypass the permission checking: // temporarily allow the user to read and write from assignments (asn.revise permission) SecurityService.pushAdvisor(new SecurityAdvisor() { public SecurityAdvice isAllowed(String userId, String function, String reference) { return SecurityAdvice.ALLOWED; } }); } List pageList = site.getPages(); Set<String> toolsCopied = new HashSet<String>(); Map transversalMap = new HashMap(); if (!((pageList == null) || (pageList.size() == 0))) { for (ListIterator i = pageList.listIterator(); i.hasNext();) { SitePage page = (SitePage) i.next(); List pageToolList = page.getTools(); if (!(pageToolList == null || pageToolList.size() == 0)) { Tool tool = ((ToolConfiguration) pageToolList.get(0)).getTool(); String toolId = tool != null ? tool.getId() : ""; if (toolId.equalsIgnoreCase("sakai.resources")) { // handle // resource // tool // specially Map<String, String> entityMap = transferCopyEntities(toolId, m_contentHostingService.getSiteCollection(oSiteId), m_contentHostingService.getSiteCollection(nSiteId)); if (entityMap != null) { transversalMap.putAll(entityMap); } } else if (toolId.equalsIgnoreCase(SITE_INFORMATION_TOOL)) { // handle Home tool specially, need to update the site infomration display url if needed String newSiteInfoUrl = transferSiteResource(oSiteId, nSiteId, site.getInfoUrl()); site.setInfoUrl(newSiteInfoUrl); } else { // other // tools // SAK-19686 - added if statement and toolsCopied.add if (!toolsCopied.contains(toolId)) { Map<String, String> entityMap = transferCopyEntities(toolId, oSiteId, nSiteId); if (entityMap != null) { transversalMap.putAll(entityMap); } toolsCopied.add(toolId); } } } } //update entity references toolsCopied = new HashSet<String>(); for (ListIterator i = pageList.listIterator(); i.hasNext();) { SitePage page = (SitePage) i.next(); List pageToolList = page.getTools(); if (!(pageToolList == null || pageToolList.size() == 0)) { Tool tool = ((ToolConfiguration) pageToolList.get(0)).getTool(); String toolId = tool != null ? tool.getId() : ""; updateEntityReferences(toolId, nSiteId, transversalMap, site); } } } if (bypassSecurity) { SecurityService.popAdvisor(); } } /** * get user answers to setup questions * @param params * @param state * @return */ protected boolean getAnswersToSetupQuestions(ParameterParser params, SessionState state) { boolean rv = true; String answerString = null; String answerId = null; Set userAnswers = new HashSet(); SiteTypeQuestions siteTypeQuestions = questionService .getSiteTypeQuestions((String) state.getAttribute(STATE_SITE_TYPE)); if (siteTypeQuestions != null) { List<SiteSetupQuestion> questions = siteTypeQuestions.getQuestions(); for (Iterator i = questions.iterator(); i.hasNext();) { SiteSetupQuestion question = (SiteSetupQuestion) i.next(); // get the selected answerId answerId = params.get(question.getId()); if (question.isRequired() && answerId == null) { rv = false; addAlert(state, rb.getString("sitesetupquestion.alert")); } else if (answerId != null) { SiteSetupQuestionAnswer answer = questionService.getSiteSetupQuestionAnswer(answerId); if (answer != null) { if (answer.getIsFillInBlank()) { // need to read the text input instead answerString = params.get("fillInBlank_" + answerId); } SiteSetupUserAnswer uAnswer = questionService.newSiteSetupUserAnswer(); uAnswer.setAnswerId(answerId); uAnswer.setAnswerString(answerString); uAnswer.setQuestionId(question.getId()); uAnswer.setUserId(SessionManager.getCurrentSessionUserId()); //update the state variable userAnswers.add(uAnswer); } } } state.setAttribute(STATE_SITE_SETUP_QUESTION_ANSWER, userAnswers); } return rv; } /** * remove related state variable for adding class * * @param state * SessionState object */ private void removeAddClassContext(SessionState state) { // remove related state variables state.removeAttribute(STATE_ADD_CLASS_MANUAL); state.removeAttribute(STATE_ADD_CLASS_PROVIDER_CHOSEN); state.removeAttribute(STATE_ADD_CLASS_PROVIDER_DESCRIPTION_CHOSEN); state.removeAttribute(STATE_MANUAL_ADD_COURSE_NUMBER); state.removeAttribute(STATE_MANUAL_ADD_COURSE_FIELDS); state.removeAttribute(STATE_SITE_QUEST_UNIQNAME); state.removeAttribute(STATE_AUTO_ADD); state.removeAttribute(STATE_IMPORT_SITE_TOOL); state.removeAttribute(STATE_IMPORT_SITES); state.removeAttribute(STATE_CM_REQUESTED_SECTIONS); state.removeAttribute(STATE_CM_SELECTED_SECTIONS); state.removeAttribute(FORM_SITEINFO_ALIASES); state.removeAttribute(FORM_SITEINFO_URL_BASE); sitePropertiesIntoState(state); } // removeAddClassContext private void updateCourseClasses(SessionState state, List notifyClasses, List requestClasses) { List providerCourseSectionList = (List) state.getAttribute(SITE_PROVIDER_COURSE_LIST); List manualCourseSectionList = (List) state.getAttribute(SITE_MANUAL_COURSE_LIST); List<SectionObject> cmRequestedCourseList = (List) state.getAttribute(STATE_CM_REQUESTED_SECTIONS); Site site = getStateSite(state); String id = site.getId(); String realmId = SiteService.siteReference(id); if ((providerCourseSectionList == null) || (providerCourseSectionList.size() == 0)) { // no section access so remove Provider Id try { AuthzGroup realmEdit1 = authzGroupService.getAuthzGroup(realmId); boolean hasNonProvidedMainroleUser = false; String maintainRoleString = realmEdit1.getMaintainRole(); Set<String> maintainRoleUsers = realmEdit1.getUsersHasRole(maintainRoleString); if (!maintainRoleUsers.isEmpty()) { for (Iterator<String> users = maintainRoleUsers.iterator(); !hasNonProvidedMainroleUser && users.hasNext();) { String userId = users.next(); if (!realmEdit1.getMember(userId).isProvided()) hasNonProvidedMainroleUser = true; } } if (!hasNonProvidedMainroleUser) { // if after the removal, there is no provider id, and there is no maintain role user anymore, show alert message and don't save the update addAlert(state, rb.getString("sitegen.siteinfolist.nomaintainuser") + maintainRoleString + "."); } else { realmEdit1.setProviderGroupId(NULL_STRING); authzGroupService.save(realmEdit1); } } catch (GroupNotDefinedException e) { M_log.error(this + ".updateCourseClasses: IdUnusedException, " + site.getTitle() + "(" + realmId + ") not found, or not an AuthzGroup object", e); addAlert(state, rb.getString("java.cannotedit")); return; } catch (AuthzPermissionException e) { M_log.error(this + ".updateCourseClasses: PermissionException, user does not have permission to edit AuthzGroup object " + site.getTitle() + "(" + realmId + "). ", e); addAlert(state, rb.getString("java.notaccess")); return; } } if ((providerCourseSectionList != null) && (providerCourseSectionList.size() != 0)) { // section access so rewrite Provider Id, don't need the current realm provider String String externalRealm = buildExternalRealm(id, state, providerCourseSectionList, null); try { AuthzGroup realmEdit2 = authzGroupService.getAuthzGroup(realmId); realmEdit2.setProviderGroupId(externalRealm); authzGroupService.save(realmEdit2); } catch (GroupNotDefinedException e) { M_log.error(this + ".updateCourseClasses: IdUnusedException, " + site.getTitle() + "(" + realmId + ") not found, or not an AuthzGroup object", e); addAlert(state, rb.getString("java.cannotclasses")); return; } catch (AuthzPermissionException e) { M_log.error(this + ".updateCourseClasses: PermissionException, user does not have permission to edit AuthzGroup object " + site.getTitle() + "(" + realmId + "). ", e); addAlert(state, rb.getString("java.notaccess")); return; } } //reload the site object after changes group realms have been removed from the site. site = getStateSite(state); // the manual request course into properties setSiteSectionProperty(manualCourseSectionList, site, PROP_SITE_REQUEST_COURSE); // the cm request course into properties setSiteSectionProperty(cmRequestedCourseList, site, STATE_CM_REQUESTED_SECTIONS); // clean the related site groups // if the group realm provider id is not listed for the site, remove the related group for (Iterator iGroups = site.getGroups().iterator(); iGroups.hasNext();) { Group group = (Group) iGroups.next(); try { AuthzGroup gRealm = authzGroupService.getAuthzGroup(group.getReference()); String gProviderId = StringUtils.trimToNull(gRealm.getProviderGroupId()); if (gProviderId != null) { if (!listContainsString(manualCourseSectionList, gProviderId) && !listContainsString(cmRequestedCourseList, gProviderId) && !listContainsString(providerCourseSectionList, gProviderId)) { // if none of those three lists contains the provider id, remove the group and realm authzGroupService.removeAuthzGroup(group.getReference()); } } } catch (Exception e) { M_log.error(this + ".updateCourseClasses: cannot remove authzgroup : " + group.getReference(), e); } } if (state.getAttribute(STATE_MESSAGE) == null) { commitSite(site); } else { } if (requestClasses != null && requestClasses.size() > 0 && state.getAttribute(STATE_MANUAL_ADD_COURSE_NUMBER) != null) { try { // send out class request notifications sendSiteRequest(state, "change", ((Integer) state.getAttribute(STATE_MANUAL_ADD_COURSE_NUMBER)).intValue(), (List<SectionObject>) state.getAttribute(STATE_MANUAL_ADD_COURSE_FIELDS), "manual"); } catch (Exception e) { M_log.error(this + ".updateCourseClasses:" + e.toString(), e); } } if (notifyClasses != null && notifyClasses.size() > 0) { try { // send out class access confirmation notifications sendSiteNotification(state, getStateSite(state), notifyClasses); } catch (Exception e) { M_log.error(this + ".updateCourseClasses:" + e.toString(), e); } } } // updateCourseClasses /** * test whether * @param list * @param providerId * @return */ boolean listContainsString(List list, String s) { boolean rv = false; if (list != null && !list.isEmpty() && s != null && s.length() != 0) { for (Object o : list) { // deals with different object type if (o instanceof SectionObject) { rv = ((SectionObject) o).getEid().equals(s); } else if (o instanceof String) { rv = ((String) o).equals(s); } // exit when find match if (rv) break; } } return rv; } private void setSiteSectionProperty(List courseSectionList, Site site, String propertyName) { if ((courseSectionList != null) && (courseSectionList.size() != 0)) { // store the requested sections in one site property StringBuffer sections = new StringBuffer(); for (int j = 0; j < courseSectionList.size();) { sections = sections.append(courseSectionList.get(j)); if (courseSectionList.get(j) instanceof SectionObject) { SectionObject so = (SectionObject) courseSectionList.get(j); sections = sections.append(so.getEid()); } else if (courseSectionList.get(j) instanceof String) { sections = sections.append((String) courseSectionList.get(j)); } j++; if (j < courseSectionList.size()) { sections = sections.append("+"); } } ResourcePropertiesEdit rp = site.getPropertiesEdit(); rp.addProperty(propertyName, sections.toString()); } else { ResourcePropertiesEdit rp = site.getPropertiesEdit(); rp.removeProperty(propertyName); } } /** * Sets selected roles for multiple users * * @param params * The ParameterParser object * @param listName * The state variable */ private void getSelectedRoles(SessionState state, ParameterParser params, String listName) { Hashtable pSelectedRoles = (Hashtable) state.getAttribute(STATE_SELECTED_PARTICIPANT_ROLES); if (pSelectedRoles == null) { pSelectedRoles = new Hashtable(); } List userList = (List) state.getAttribute(listName); for (int i = 0; i < userList.size(); i++) { String userId = null; if (listName.equalsIgnoreCase(STATE_ADD_PARTICIPANTS)) { userId = ((Participant) userList.get(i)).getUniqname(); } else if (listName.equalsIgnoreCase(STATE_SELECTED_USER_LIST)) { userId = (String) userList.get(i); } if (userId != null) { String rId = StringUtils.trimToNull(params.getString("role" + userId)); if (rId == null) { addAlert(state, rb.getString("java.rolefor") + " " + userId + ". "); pSelectedRoles.remove(userId); } else { pSelectedRoles.put(userId, rId); } } } state.setAttribute(STATE_SELECTED_PARTICIPANT_ROLES, pSelectedRoles); } // getSelectedRoles /** * dispatch function for changing participants roles */ public void doSiteinfo_edit_role(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); ParameterParser params = data.getParameters(); String option = params.getString("option"); // dispatch if (option.equalsIgnoreCase("same_role_true")) { state.setAttribute(STATE_CHANGEROLE_SAMEROLE, Boolean.TRUE); state.setAttribute(STATE_CHANGEROLE_SAMEROLE_ROLE, params.getString("role_to_all")); } else if (option.equalsIgnoreCase("same_role_false")) { state.setAttribute(STATE_CHANGEROLE_SAMEROLE, Boolean.FALSE); state.removeAttribute(STATE_CHANGEROLE_SAMEROLE_ROLE); if (state.getAttribute(STATE_SELECTED_PARTICIPANT_ROLES) == null) { state.setAttribute(STATE_SELECTED_PARTICIPANT_ROLES, new Hashtable()); } } else if (option.equalsIgnoreCase("continue")) { doContinue(data); } else if (option.equalsIgnoreCase("back")) { doBack(data); } else if (option.equalsIgnoreCase("cancel")) { doCancel(data); } } // doSiteinfo_edit_role /** * save changes to site global access */ public void doSiteinfo_save_globalAccess(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); Site s = getStateSite(state); boolean joinable = ((Boolean) state.getAttribute("form_joinable")).booleanValue(); s.setJoinable(joinable); if (joinable) { // set the joiner role String joinerRole = (String) state.getAttribute("form_joinerRole"); s.setJoinerRole(joinerRole); // Handle invalid joinable site settings try { // Update site properties for joinable site settings JoinableSiteSettings.updateSitePropertiesFromStateOnSiteInfoSaveGlobalAccess(s.getPropertiesEdit(), state); } catch (InvalidJoinableSiteSettingsException invalidSettingsException) { addAlert(state, invalidSettingsException.getFormattedMessage(rb)); } } if (state.getAttribute(STATE_MESSAGE) == null) { // release site edit commitSite(s); state.setAttribute(STATE_TEMPLATE_INDEX, "18"); } } // doSiteinfo_save_globalAccess /** * updateSiteAttributes * */ private void updateSiteAttributes(SessionState state) { SiteInfo siteInfo = new SiteInfo(); if (state.getAttribute(STATE_SITE_INFO) != null) { siteInfo = (SiteInfo) state.getAttribute(STATE_SITE_INFO); } else { M_log.warn("SiteAction.updateSiteAttributes STATE_SITE_INFO == null"); return; } Site site = getStateSite(state); if (site != null) { if (StringUtils.trimToNull(siteInfo.title) != null) { site.setTitle(siteInfo.title); } if (siteInfo.description != null) { site.setDescription(siteInfo.description); } site.setPublished(siteInfo.published); setAppearance(state, site, siteInfo.iconUrl); site.setJoinable(siteInfo.joinable); if (StringUtils.trimToNull(siteInfo.joinerRole) != null) { site.setJoinerRole(siteInfo.joinerRole); } // Make changes and then put changed site back in state String id = site.getId(); // bjones86 - SAK-24423 - update site properties for joinable site settings JoinableSiteSettings.updateSitePropertiesFromStateOnUpdateSiteAttributes(site, state); try { SiteService.save(site); } catch (IdUnusedException e) { // TODO: } catch (PermissionException e) { // TODO: } if (SiteService.allowUpdateSite(id)) { try { SiteService.getSite(id); state.setAttribute(STATE_SITE_INSTANCE_ID, id); } catch (IdUnusedException e) { M_log.error(this + ".updateSiteAttributes: IdUnusedException " + siteInfo.getTitle() + "(" + id + ") not found", e); } } // no permission else { addAlert(state, rb.getString("java.makechanges")); M_log.warn(this + ".updateSiteAttributes: PermissionException " + siteInfo.getTitle() + "(" + id + ")"); } } } // updateSiteAttributes /** * %%% legacy properties, to be removed */ private void updateSiteInfo(ParameterParser params, SessionState state) { SiteInfo siteInfo = new SiteInfo(); if (state.getAttribute(STATE_SITE_INFO) != null) { siteInfo = (SiteInfo) state.getAttribute(STATE_SITE_INFO); } siteInfo.site_type = (String) state.getAttribute(STATE_SITE_TYPE); // title boolean hasRosterAttached = params.getString("hasRosterAttached") != null ? Boolean.getBoolean(params.getString("hasRosterAttached")) : false; if ((siteTitleEditable(state, siteInfo.site_type) || !hasRosterAttached) && params.getString("title") != null) { // site titel is editable and could not be null String title = StringUtils.trimToNull(params.getString("title")); siteInfo.title = title; if (title == null) { addAlert(state, rb.getString("java.specify") + " "); } // check for site title length else if (title.length() > SiteConstants.SITE_GROUP_TITLE_LIMIT) { addAlert(state, rb.getFormattedMessage("site_group_title_length_limit", new Object[] { SiteConstants.SITE_GROUP_TITLE_LIMIT })); } } if (params.getString("description") != null) { StringBuilder alertMsg = new StringBuilder(); String description = params.getString("description"); siteInfo.description = FormattedText.processFormattedText(description, alertMsg); } if (params.getString("short_description") != null) { siteInfo.short_description = params.getString("short_description"); } String skin = params.getString("skin"); if (skin != null) { // if there is a skin input for course site skin = StringUtils.trimToNull(skin); siteInfo.iconUrl = skin; } else { // if ther is a icon input for non-course site String icon = StringUtils.trimToNull(params.getString("icon")); if (icon != null) { if (icon.endsWith(PROTOCOL_STRING)) { addAlert(state, rb.getString("alert.protocol")); } siteInfo.iconUrl = icon; } else { siteInfo.iconUrl = ""; } } if (params.getString("additional") != null) { siteInfo.additional = params.getString("additional"); } if (params.getString("iconUrl") != null) { siteInfo.iconUrl = params.getString("iconUrl"); } else if (params.getString("skin") != null) { siteInfo.iconUrl = params.getString("skin"); } if (params.getString("joinerRole") != null) { siteInfo.joinerRole = params.getString("joinerRole"); } if (params.getString("joinable") != null) { boolean joinable = params.getBoolean("joinable"); siteInfo.joinable = joinable; if (!joinable) siteInfo.joinerRole = NULL_STRING; } if (params.getString("itemStatus") != null) { siteInfo.published = Boolean.valueOf(params.getString("itemStatus")).booleanValue(); } // bjones86 - SAK-24423 - update site info for joinable site settings JoinableSiteSettings.updateSiteInfoFromParams(params, siteInfo); // site contact information String name = StringUtils.trimToEmpty(params.getString("siteContactName")); if (name.length() == 0) { addAlert(state, rb.getString("alert.sitediinf.sitconnam")); } siteInfo.site_contact_name = name; String email = StringUtils.trimToEmpty(params.getString("siteContactEmail")); if (email != null) { if (!email.isEmpty() && !EmailValidator.getInstance().isValid(email)) { // invalid email addAlert(state, rb.getFormattedMessage("java.invalid.email", new Object[] { FormattedText.escapeHtml(email, false) })); } siteInfo.site_contact_email = email; } int aliasCount = params.getInt("alias_count", 0); siteInfo.siteRefAliases.clear(); for (int j = 0; j < aliasCount; j++) { String alias = StringUtils.trimToNull(params.getString("alias_" + j)); if (alias == null) { continue; } // Kernel will force these to lower case anyway. Forcing // to lower case whenever reading out of the form simplifies // comparisons at save time, though, and provides consistent // on-screen display. alias = alias.toLowerCase(); // An invalid alias will set an alert, which theoretically // disallows further progress in the workflow, but we // still need to re-render the invalid form contents. // Thus siteInfo.aliases contains all input aliases, even if // invalid. (Same thing happens above for email.) validateSiteAlias(alias, state); siteInfo.siteRefAliases.add(alias); } state.setAttribute(STATE_SITE_INFO, siteInfo); } // updateSiteInfo private boolean validateSiteAlias(String aliasId, SessionState state) { if ((aliasId = StringUtils.trimToNull(aliasId)) == null) { addAlert(state, rb.getFormattedMessage("java.alias.isinval", new Object[] { aliasId })); return false; } boolean isSimpleResourceName = aliasId.equals(Validator.escapeResourceName(aliasId)); boolean isSimpleUrl = aliasId.equals(Validator.escapeUrl(aliasId)); if (!(isSimpleResourceName) || !(isSimpleUrl)) { // The point of these site aliases is to have easy-to-recall, // easy-to-guess URLs. So we take a very conservative approach // here and disallow any aliases which would require special // encoding or would simply be ignored when building a valid // resource reference or outputting that reference as a URL. addAlert(state, rb.getFormattedMessage("java.alias.isinval", new Object[] { aliasId })); return false; } else { String currentSiteId = StringUtils.trimToNull((String) state.getAttribute(STATE_SITE_INSTANCE_ID)); boolean editingSite = currentSiteId != null; try { String targetRef = aliasService.getTarget(aliasId); if (editingSite) { String siteRef = SiteService.siteReference(currentSiteId); boolean targetsCurrentSite = siteRef.equals(targetRef); if (!(targetsCurrentSite)) { addAlert(state, rb.getFormattedMessage("java.alias.exists", new Object[] { aliasId })); return false; } } else { addAlert(state, rb.getFormattedMessage("java.alias.exists", new Object[] { aliasId })); return false; } } catch (IdUnusedException e) { // No conflicting aliases } return true; } } /** * getParticipantList * */ private Collection getParticipantList(SessionState state) { List members = new Vector(); String siteId = (String) state.getAttribute(STATE_SITE_INSTANCE_ID); List providerCourseList = null; providerCourseList = SiteParticipantHelper.getProviderCourseList(siteId); if (providerCourseList != null && providerCourseList.size() > 0) { state.setAttribute(SITE_PROVIDER_COURSE_LIST, providerCourseList); } Collection participants = SiteParticipantHelper.prepareParticipants(siteId, providerCourseList); state.setAttribute(STATE_PARTICIPANT_LIST, participants); return participants; } // getParticipantList /** * getRoles * */ private List getRoles(SessionState state) { List roles = new Vector(); String realmId = SiteService.siteReference((String) state.getAttribute(STATE_SITE_INSTANCE_ID)); try { AuthzGroup realm = authzGroupService.getAuthzGroup(realmId); // Filter the roles so we only display user roles for (Role role : (Set<Role>) realm.getRoles()) { if (authzGroupService.isRoleAssignable(role.getId())) { roles.add(role); } } Collections.sort(roles); } catch (GroupNotDefinedException e) { M_log.error(this + ".getRoles: IdUnusedException " + realmId, e); } return roles; } // getRoles /** * getRoles * * bjones86 - SAK-23257 - added state and siteType parameters so list * of joiner roles can respect the restricted role lists in sakai.properties. * */ private List<Role> getJoinerRoles(String realmId, SessionState state, String siteType) { List roles = new ArrayList(); /** related to SAK-18462, this is a list of permissions that the joinable roles shouldn't have ***/ String[] prohibitPermissionForJoinerRole = ServerConfigurationService .getStrings("siteinfo.prohibited_permission_for_joiner_role"); if (prohibitPermissionForJoinerRole == null) { prohibitPermissionForJoinerRole = new String[] { "site.upd" }; } if (realmId != null) { try { AuthzGroup realm = authzGroupService.getAuthzGroup(realmId); // get all roles that allows at least one permission in the list Set<String> permissionAllowedRoleIds = new HashSet<String>(); for (String permission : prohibitPermissionForJoinerRole) { permissionAllowedRoleIds.addAll(realm.getRolesIsAllowed(permission)); } // bjones86 - SAK-23257 List<Role> allowedRoles = null; Set<String> restrictedRoles = null; if (null == state.getAttribute(STATE_SITE_INSTANCE_ID)) { restrictedRoles = SiteParticipantHelper .getRestrictedRoles(state.getAttribute(STATE_SITE_TYPE).toString()); } else { allowedRoles = SiteParticipantHelper.getAllowedRoles(siteType, getRoles(state)); } for (Role role : realm.getRoles()) { if (isUserRole(role) && (permissionAllowedRoleIds == null || permissionAllowedRoleIds != null && !permissionAllowedRoleIds.contains(role.getId()))) { // bjones86 - SAK-23257 if (allowedRoles != null && allowedRoles.contains(role)) { roles.add(role); } else if (restrictedRoles != null && (!restrictedRoles.contains(role.getId()) || !restrictedRoles.contains(role.getId().toLowerCase()))) { roles.add(role); } } } Collections.sort(roles); } catch (GroupNotDefinedException e) { M_log.error(this + ".getRoles: IdUnusedException " + realmId, e); } } return roles; } // getRolesWithoutPermission private boolean isUserRole(Role role) { return !role.getId().startsWith("."); } private void addSynopticTool(SitePage page, String toolId, String toolTitle, String layoutHint, int position) { page.setLayout(SitePage.LAYOUT_DOUBLE_COL); // Add synoptic announcements tool ToolConfiguration tool = page.addTool(); Tool reg = ToolManager.getTool(toolId); tool.setTool(toolId, reg); tool.setTitle(toolTitle); tool.setLayoutHints(layoutHint); // count how many synoptic tools in the second/right column int totalSynopticTools = 0; for (ToolConfiguration t : page.getTools()) { if (t.getToolId() != null && SYNOPTIC_TOOL_ID_MAP.containsKey(t.getToolId())) { totalSynopticTools++; } } // now move the newly added synoptic tool to proper position for (int i = 0; i < (totalSynopticTools - position - 1); i++) { tool.moveUp(); } } private void saveFeatures(ParameterParser params, SessionState state, Site site) { String siteType = checkNullSiteType(state, site.getType(), site.getId()); // get the list of Worksite Setup configured pages List wSetupPageList = state.getAttribute(STATE_WORKSITE_SETUP_PAGE_LIST) != null ? (List) state.getAttribute(STATE_WORKSITE_SETUP_PAGE_LIST) : new Vector(); Set multipleToolIdSet = (Set) state.getAttribute(STATE_MULTIPLE_TOOL_ID_SET); // get the map of titles of multiple tool instances Map multipleToolIdTitleMap = state.getAttribute(STATE_MULTIPLE_TOOL_ID_TITLE_MAP) != null ? (Map) state.getAttribute(STATE_MULTIPLE_TOOL_ID_TITLE_MAP) : new HashMap(); WorksiteSetupPage wSetupPage = new WorksiteSetupPage(); WorksiteSetupPage wSetupHome = new WorksiteSetupPage(); List pageList = new Vector(); // declare some flags used in making decisions about Home, whether to // add, remove, or do nothing boolean hasHome = false; String homePageId = null; boolean homeInWSetupPageList = false; List chosenList = (List) state.getAttribute(STATE_TOOL_REGISTRATION_SELECTED_LIST); boolean hasEmail = false; boolean hasSiteInfo = false; // tools to be imported from other sites? Hashtable importTools = null; if (state.getAttribute(STATE_IMPORT_SITE_TOOL) != null) { importTools = (Hashtable) state.getAttribute(STATE_IMPORT_SITE_TOOL); } // Home tool chosen? if (chosenList.contains(TOOL_ID_HOME)) { // add home tool later hasHome = true; } // order the id list chosenList = orderToolIds(state, siteType, chosenList, false); // Special case - Worksite Setup Home comes from a hardcoded checkbox on // the vm template rather than toolRegistrationList // see if Home was chosen for (ListIterator j = chosenList.listIterator(); j.hasNext();) { String choice = (String) j.next(); if ("sakai.mailbox".equals(choice)) { hasEmail = true; String alias = StringUtils.trimToNull((String) state.getAttribute(STATE_TOOL_EMAIL_ADDRESS)); String channelReference = mailArchiveChannelReference(site.getId()); if (alias != null) { if (!Validator.checkEmailLocal(alias)) { addAlert(state, rb.getString("java.theemail")); } else if (!aliasService.allowSetAlias(alias, channelReference)) { addAlert(state, rb.getString("java.addalias")); } else { try { String target = aliasService.getTarget(alias); boolean targetsThisSite = site.getReference().equals(target) || channelReference.equals(target); if (!(targetsThisSite)) { addAlert(state, rb.getString("java.emailinuse") + " "); } } catch (IdUnusedException ee) { try { aliasService.setAlias(alias, channelReference); } catch (IdUsedException exception) { M_log.error( this + ".saveFeatures setAlias IdUsedException:" + exception.getMessage() + " alias=" + alias + " channelReference=" + channelReference, exception); } catch (IdInvalidException exception) { M_log.error( this + ".saveFeatures setAlias IdInvalidException:" + exception.getMessage() + " alias=" + alias + " channelReference=" + channelReference, exception); } catch (PermissionException exception) { M_log.error(this + ".saveFeatures setAlias PermissionException:" + exception.getMessage() + " alias=" + alias + " channelReference=" + channelReference, exception); } } } } } else if (choice.equals(TOOL_ID_SITEINFO)) { hasSiteInfo = true; } } // see if Home and/or Help in the wSetupPageList (can just check title // here, because we checked patterns before adding to the list) for (ListIterator i = wSetupPageList.listIterator(); i.hasNext();) { wSetupPage = (WorksiteSetupPage) i.next(); if (isHomePage(site.getPage(wSetupPage.getPageId()))) { homeInWSetupPageList = true; homePageId = wSetupPage.getPageId(); break; } } if (hasHome) { SitePage page = site.getPage(homePageId); if (!homeInWSetupPageList) { // if Home is chosen and Home is not in wSetupPageList, add Home // to site and wSetupPageList page = site.addPage(); page.setTitle(rb.getString("java.home")); wSetupHome.pageId = page.getId(); wSetupHome.pageTitle = page.getTitle(); wSetupHome.toolId = TOOL_ID_HOME; wSetupPageList.add(wSetupHome); } // the list tools on the home page List<ToolConfiguration> toolList = page.getTools(); // get tool id set for Home page from configuration List<String> homeToolIds = getHomeToolIds(state, !homeInWSetupPageList, page); // count int nonSynopticToolIndex = 0, synopticToolIndex = 0; for (String homeToolId : homeToolIds) { if (!SYNOPTIC_TOOL_ID_MAP.containsKey(homeToolId)) { if (!pageHasToolId(toolList, homeToolId)) { // not a synoptic tool and is not in Home page yet, just add it Tool reg = ToolManager.getTool(homeToolId); if (reg != null) { ToolConfiguration tool = page.addTool(); tool.setTool(homeToolId, reg); tool.setTitle(reg.getTitle() != null ? reg.getTitle() : ""); tool.setLayoutHints("0," + nonSynopticToolIndex++); } } } else { // synoptic tool List<String> parentToolList = (List<String>) SYNOPTIC_TOOL_ID_MAP.get(homeToolId); List chosenListClone = new Vector(); // chosenlist may have things like bcf89cd4-fa3a-4dda-80bd-ed0b89981ce7sakai.chat // get list of the actual tool names List<String> chosenOrigToolList = new ArrayList<String>(); for (String chosenTool : (List<String>) chosenList) chosenOrigToolList.add(findOriginalToolId(state, chosenTool)); chosenListClone.addAll(chosenOrigToolList); boolean hasAnyParentToolId = chosenListClone.removeAll(parentToolList); //first check whether the parent tool is available in site but its parent tool is no longer selected if (pageHasToolId(toolList, homeToolId)) { if (!hasAnyParentToolId && !SiteService.isUserSite(site.getId())) { for (ListIterator iToolList = toolList.listIterator(); iToolList.hasNext();) { ToolConfiguration tConf = (ToolConfiguration) iToolList.next(); // avoid NPE when the tool definition is missing if (tConf.getTool() != null && homeToolId.equals(tConf.getTool().getId())) { page.removeTool((ToolConfiguration) tConf); break; } } } else { synopticToolIndex++; } } // then add those synoptic tools which wasn't there before if (!pageHasToolId(toolList, homeToolId) && hasAnyParentToolId) { try { // use value from map to find an internationalized tool title String toolTitleText = rb.getString(SYNOPTIC_TOOL_TITLE_MAP.get(homeToolId)); addSynopticTool(page, homeToolId, toolTitleText, synopticToolIndex + ",1", synopticToolIndex++); } catch (Exception e) { M_log.error(this + ".saveFeatures addSynotpicTool: " + e.getMessage() + " site id = " + site.getId() + " tool = " + homeToolId, e); } } } } if (page.getTools().size() == 1) { // only use one column layout page.setLayout(SitePage.LAYOUT_SINGLE_COL); } // mark this page as Home page inside its property if (page.getProperties().getProperty(SitePage.IS_HOME_PAGE) == null) { page.getPropertiesEdit().addProperty(SitePage.IS_HOME_PAGE, Boolean.TRUE.toString()); } } // add Home // if Home is in wSetupPageList and not chosen, remove Home feature from // wSetupPageList and site if (!hasHome && homeInWSetupPageList) { // remove Home from wSetupPageList for (ListIterator i = wSetupPageList.listIterator(); i.hasNext();) { WorksiteSetupPage comparePage = (WorksiteSetupPage) i.next(); SitePage sitePage = site.getPage(comparePage.getPageId()); if (sitePage != null && isHomePage(sitePage)) { // remove the Home page site.removePage(sitePage); wSetupPageList.remove(comparePage); break; } } } // declare flags used in making decisions about whether to add, remove, // or do nothing boolean inChosenList; boolean inWSetupPageList; Set categories = new HashSet(); // UMICH 1035 categories.add(siteType); categories.add(SiteTypeUtil.getTargetSiteType(siteType)); Set toolRegistrationSet = ToolManager.findTools(categories, null); // first looking for any tool for removal Vector removePageIds = new Vector(); for (ListIterator k = wSetupPageList.listIterator(); k.hasNext();) { wSetupPage = (WorksiteSetupPage) k.next(); String pageToolId = wSetupPage.getToolId(); // use page id + tool id for multiple tool instances if (isMultipleInstancesAllowed(findOriginalToolId(state, pageToolId))) { pageToolId = wSetupPage.getPageId() + pageToolId; } inChosenList = false; for (ListIterator j = chosenList.listIterator(); j.hasNext();) { String toolId = (String) j.next(); if (pageToolId.equals(toolId)) { inChosenList = true; } } // exclude the Home page if there is any if (!inChosenList && !(homePageId != null && wSetupPage.getPageId().equals(homePageId))) { removePageIds.add(wSetupPage.getPageId()); } } for (int i = 0; i < removePageIds.size(); i++) { // if the tool exists in the wSetupPageList, remove it from the site String removeId = (String) removePageIds.get(i); SitePage sitePage = site.getPage(removeId); site.removePage(sitePage); // and remove it from wSetupPageList for (ListIterator k = wSetupPageList.listIterator(); k.hasNext();) { wSetupPage = (WorksiteSetupPage) k.next(); if (!wSetupPage.getPageId().equals(removeId)) { wSetupPage = null; } } if (wSetupPage != null) { wSetupPageList.remove(wSetupPage); } } // then looking for any tool to add for (ListIterator j = orderToolIds(state, siteType, chosenList, false).listIterator(); j.hasNext();) { String toolId = (String) j.next(); boolean multiAllowed = isMultipleInstancesAllowed(findOriginalToolId(state, toolId)); // exclude Home tool if (!toolId.equals(TOOL_ID_HOME)) { // Is the tool in the wSetupPageList? inWSetupPageList = false; for (ListIterator k = wSetupPageList.listIterator(); k.hasNext();) { wSetupPage = (WorksiteSetupPage) k.next(); String pageToolId = wSetupPage.getToolId(); // use page Id + toolId for multiple tool instances if (isMultipleInstancesAllowed(findOriginalToolId(state, pageToolId))) { pageToolId = wSetupPage.getPageId() + pageToolId; } if (pageToolId.equals(toolId)) { inWSetupPageList = true; // but for tool of multiple instances, need to change the title if (multiAllowed) { SitePage pEdit = (SitePage) site.getPage(wSetupPage.pageId); pEdit.setTitle((String) multipleToolIdTitleMap.get(toolId)); List toolList = pEdit.getTools(); for (ListIterator jTool = toolList.listIterator(); jTool.hasNext();) { ToolConfiguration tool = (ToolConfiguration) jTool.next(); String tId = tool.getTool().getId(); if (isMultipleInstancesAllowed(findOriginalToolId(state, tId))) { // set tool title tool.setTitle((String) multipleToolIdTitleMap.get(toolId)); // save tool configuration saveMultipleToolConfiguration(state, tool, toolId); } } } } } if (inWSetupPageList) { // if the tool already in the list, do nothing so to save the // option settings } else { // if in chosen list but not in wSetupPageList, add it to the // site (one tool on a page) Tool toolRegFound = null; for (Iterator i = toolRegistrationSet.iterator(); i.hasNext();) { Tool toolReg = (Tool) i.next(); String toolRegId = toolReg.getId(); if (toolId.equals(toolRegId)) { toolRegFound = toolReg; break; } else if (multiAllowed && toolId.startsWith(toolRegId)) { try { // in case of adding multiple tools, tool id is of format ORIGINAL_TOOL_ID + INDEX_NUMBER Integer.parseInt(toolId.replace(toolRegId, "")); toolRegFound = toolReg; break; } catch (Exception parseException) { // ignore parse exception } } } if (toolRegFound != null) { // we know such a tool, so add it WorksiteSetupPage addPage = new WorksiteSetupPage(); SitePage page = site.addPage(); addPage.pageId = page.getId(); if (multiAllowed) { // set tool title page.setTitle((String) multipleToolIdTitleMap.get(toolId)); page.setTitleCustom(true); } else { // other tools with default title page.setTitle(toolRegFound.getTitle()); } page.setLayout(SitePage.LAYOUT_SINGLE_COL); // if so specified in the tool's registration file, // configure the tool's page to open in a new window. if ("true".equals(toolRegFound.getRegisteredConfig().getProperty("popup"))) { page.setPopup(true); } ToolConfiguration tool = page.addTool(); tool.setTool(toolRegFound.getId(), toolRegFound); addPage.toolId = toolId; wSetupPageList.add(addPage); // set tool title if (multiAllowed) { // set tool title tool.setTitle((String) multipleToolIdTitleMap.get(toolId)); // save tool configuration saveMultipleToolConfiguration(state, tool, toolId); } else { tool.setTitle(toolRegFound.getTitle()); } } } } } // for // commit commitSite(site); site = refreshSiteObject(site); // check the status of external lti tools // 1. any lti tool to remove? HashMap<String, Map<String, Object>> ltiTools = state.getAttribute(STATE_LTITOOL_SELECTED_LIST) != null ? (HashMap<String, Map<String, Object>>) state.getAttribute(STATE_LTITOOL_SELECTED_LIST) : null; Map<String, Map<String, Object>> oldLtiTools = state .getAttribute(STATE_LTITOOL_EXISTING_SELECTED_LIST) != null ? (Map<String, Map<String, Object>>) state .getAttribute(STATE_LTITOOL_EXISTING_SELECTED_LIST) : null; ; if (oldLtiTools != null) { // get all the old enalbed lti tools for (String oldLtiToolsId : oldLtiTools.keySet()) { if (ltiTools == null || !ltiTools.containsKey(oldLtiToolsId)) { // the tool is not selectd now. Remove it from site Map<String, Object> oldLtiToolValues = oldLtiTools.get(oldLtiToolsId); Long contentKey = Long.valueOf(oldLtiToolValues.get("contentKey").toString()); m_ltiService.deleteContent(contentKey); // refresh the site object site = refreshSiteObject(site); } } } // 2. any lti tool to add? if (ltiTools != null) { // then looking for any lti tool to add for (Map.Entry<String, Map<String, Object>> ltiTool : ltiTools.entrySet()) { String ltiToolId = ltiTool.getKey(); if (!oldLtiTools.containsKey(ltiToolId)) { Map<String, Object> toolValues = ltiTool.getValue(); Properties reqProperties = (Properties) toolValues.get("reqProperties"); if (reqProperties == null) { reqProperties = new Properties(); } Object retval = m_ltiService.insertToolContent(null, ltiToolId, reqProperties, site.getId()); if (retval instanceof String) { // error inserting tool content addAlert(state, (String) retval); break; } else { // success inserting tool content String pageTitle = reqProperties.getProperty("pagetitle"); retval = m_ltiService.insertToolSiteLink(((Long) retval).toString(), pageTitle, site.getId()); if (retval instanceof String) { addAlert(state, ((String) retval).substring(2)); break; } } } // refresh the site object site = refreshSiteObject(site); } } // if // reorder Home and Site Info only if the site has not been customized order before if (!site.isCustomPageOrdered()) { // the steps for moving page within the list int moves = 0; if (hasHome) { SitePage homePage = null; // Order tools - move Home to the top - first find it pageList = site.getPages(); if (pageList != null && pageList.size() != 0) { for (ListIterator i = pageList.listIterator(); i.hasNext();) { SitePage page = (SitePage) i.next(); if (isHomePage(page)) { homePage = page; break; } } } if (homePage != null) { moves = pageList.indexOf(homePage); for (int n = 0; n < moves; n++) { homePage.moveUp(); } } } // if Site Info is newly added, more it to the last if (hasSiteInfo) { SitePage siteInfoPage = null; pageList = site.getPages(); String[] toolIds = { TOOL_ID_SITEINFO }; if (pageList != null && pageList.size() != 0) { for (ListIterator i = pageList.listIterator(); siteInfoPage == null && i.hasNext();) { SitePage page = (SitePage) i.next(); int s = page.getTools(toolIds).size(); if (s > 0) { siteInfoPage = page; break; } } if (siteInfoPage != null) { // move home from it's index to the first position moves = pageList.indexOf(siteInfoPage); for (int n = moves; n < pageList.size(); n++) { siteInfoPage.moveDown(); } } } } } // if there is no email tool chosen if (!hasEmail) { state.removeAttribute(STATE_TOOL_EMAIL_ADDRESS); } // commit commitSite(site); site = refreshSiteObject(site); // import importToolIntoSite(chosenList, importTools, site); // SAK-22384 add LaTeX (MathJax) support if (MathJaxEnabler.prepareMathJaxToolSettingsForSave(site, state)) { commitSite(site); } } // saveFeatures /** * refresh site object * @param site * @return */ private Site refreshSiteObject(Site site) { // refresh the site object try { site = SiteService.getSite(site.getId()); } catch (Exception e) { // error getting site after tool modification M_log.warn(this + " - cannot get site " + site.getId() + " after inserting lti tools"); } return site; } /** * Save configuration values for multiple tool instances */ private void saveMultipleToolConfiguration(SessionState state, ToolConfiguration tool, String toolId) { // get the configuration of multiple tool instance HashMap<String, HashMap<String, String>> multipleToolConfiguration = state .getAttribute(STATE_MULTIPLE_TOOL_CONFIGURATION) != null ? (HashMap<String, HashMap<String, String>>) state .getAttribute(STATE_MULTIPLE_TOOL_CONFIGURATION) : new HashMap<String, HashMap<String, String>>(); // set tool attributes HashMap<String, String> attributes = multipleToolConfiguration.get(toolId); if (attributes != null) { for (Map.Entry<String, String> attributeEntry : attributes.entrySet()) { String attribute = attributeEntry.getKey(); String attributeValue = attributeEntry.getValue(); // if we have a value if (attributeValue != null) { // if this value is not the same as the tool's registered, set it in the placement if (!attributeValue.equals(tool.getTool().getRegisteredConfig().getProperty(attribute))) { tool.getPlacementConfig().setProperty(attribute, attributeValue); } // otherwise clear it else { tool.getPlacementConfig().remove(attribute); } } // if no value else { tool.getPlacementConfig().remove(attribute); } } } } /** * Is the tool stealthed or hidden * @param toolId * @return */ private boolean notStealthOrHiddenTool(String toolId) { Tool tool = ToolManager.getTool(toolId); Set<Tool> tools = ToolManager.findTools(Collections.emptySet(), null); boolean result = tool != null && tools.contains(tool); return result; } /** * Is the siteType listed in the tool properties list of categories? * @param siteType * @param tool * @return * SAK 23808 */ private boolean isSiteTypeInToolCategory(String siteType, Tool tool) { Set<Tool> tools = ToolManager.findTools(Collections.emptySet(), null); Set<String> categories = tool.getCategories(); Iterator<String> iterator = categories.iterator(); while (iterator.hasNext()) { String nextCat = iterator.next(); if (nextCat.equals(siteType)) { return true; } } return false; } /** * getFeatures gets features for a new site * */ private void getFeatures(ParameterParser params, SessionState state, String continuePageIndex) { List idsSelected = new Vector(); List existTools = state.getAttribute(STATE_TOOL_REGISTRATION_OLD_SELECTED_LIST) == null ? new Vector() : (List) state.getAttribute(STATE_TOOL_REGISTRATION_OLD_SELECTED_LIST); // to reset the state variable of the multiple tool instances Set multipleToolIdSet = state.getAttribute(STATE_MULTIPLE_TOOL_ID_SET) != null ? (Set) state.getAttribute(STATE_MULTIPLE_TOOL_ID_SET) : new HashSet(); // get the map of titles of multiple tool instances Map multipleToolIdTitleMap = state.getAttribute(STATE_MULTIPLE_TOOL_ID_TITLE_MAP) != null ? (Map) state.getAttribute(STATE_MULTIPLE_TOOL_ID_TITLE_MAP) : new HashMap(); // related to LTI Tool selection Map<String, Map<String, Object>> existingLtiIds = state .getAttribute(STATE_LTITOOL_EXISTING_SELECTED_LIST) != null ? (Map<String, Map<String, Object>>) state .getAttribute(STATE_LTITOOL_EXISTING_SELECTED_LIST) : null; HashMap<String, Map<String, Object>> ltiTools = (HashMap<String, Map<String, Object>>) state .getAttribute(STATE_LTITOOL_LIST); HashMap<String, Map<String, Object>> ltiSelectedTools = new HashMap<String, Map<String, Object>>(); boolean goToToolConfigPage = false; boolean homeSelected = false; // lti tool selection boolean ltiToolSelected = false; // Add new pages and tools, if any if (params.getStrings("selectedTools") == null && params.getStrings("selectedLtiTools") == null) { addAlert(state, rb.getString("atleastonetool")); } else { List l = new ArrayList(Arrays.asList(params.getStrings("selectedTools"))); // toolId's of chosen tools for (int i = 0; i < l.size(); i++) { String toolId = (String) l.get(i); if (toolId.equals(TOOL_ID_HOME)) { homeSelected = true; if (!idsSelected.contains(toolId)) idsSelected.add(toolId); } else if (toolId.startsWith(LTITOOL_ID_PREFIX)) { String ltiToolId = toolId.substring(LTITOOL_ID_PREFIX.length()); // whether there is any lti tool been selected if (existingLtiIds == null) { ltiToolSelected = true; } else { if (!existingLtiIds.keySet().contains(ltiToolId)) { // there are some new lti tool(s) selected ltiToolSelected = true; } } // add tool entry to list ltiSelectedTools.put(ltiToolId, ltiTools.get(ltiToolId)); } else { String originId = findOriginalToolId(state, toolId); if (isMultipleInstancesAllowed(originId)) { // if user is adding either EmailArchive tool, News tool // or Web Content tool, go to the Customize page for the // tool if (!existTools.contains(toolId)) { goToToolConfigPage = true; if (!multipleToolIdSet.contains(toolId)) multipleToolIdSet.add(toolId); if (!multipleToolIdTitleMap.containsKey(toolId)) { // reset tool title if there is a different title config setting String titleConfig = ServerConfigurationService .getString(CONFIG_TOOL_TITLE + originId); if (titleConfig != null && titleConfig.length() > 0) { multipleToolIdTitleMap.put(toolId, titleConfig); } else { multipleToolIdTitleMap.put(toolId, ToolManager.getTool(originId).getTitle()); } } } } else if ("sakai.mailbox".equals(toolId)) { // get the email alias when an Email Archive tool // has been selected String alias = getSiteAlias( mailArchiveChannelReference((String) state.getAttribute(STATE_SITE_INSTANCE_ID))); if (alias != null) { state.setAttribute(STATE_TOOL_EMAIL_ADDRESS, alias); } // go to the config page if (!existTools.contains(toolId)) { goToToolConfigPage = true; } } if (!idsSelected.contains(toolId)) idsSelected.add(toolId); } } state.setAttribute(STATE_TOOL_HOME_SELECTED, Boolean.valueOf(homeSelected)); if (!ltiSelectedTools.isEmpty()) { state.setAttribute(STATE_LTITOOL_SELECTED_LIST, ltiSelectedTools); } else { state.removeAttribute(STATE_LTITOOL_SELECTED_LIST); } } state.setAttribute(STATE_TOOL_REGISTRATION_SELECTED_LIST, idsSelected); // List of ToolRegistration toolId's // in case of import String importString = params.getString("import"); if (importString != null && importString.equalsIgnoreCase(Boolean.TRUE.toString())) { state.setAttribute(STATE_IMPORT, Boolean.TRUE); List importSites = new Vector(); if (params.getStrings("importSites") != null) { importSites = new ArrayList(Arrays.asList(params.getStrings("importSites"))); } if (importSites.size() == 0) { addAlert(state, rb.getString("java.toimport") + " "); } else { Hashtable sites = new Hashtable(); for (int index = 0; index < importSites.size(); index++) { try { Site s = SiteService.getSite((String) importSites.get(index)); if (!sites.containsKey(s)) { sites.put(s, new Vector()); } } catch (IdUnusedException e) { } } state.setAttribute(STATE_IMPORT_SITES, sites); } } else { state.removeAttribute(STATE_IMPORT); } // of // ToolRegistration // toolId's if (state.getAttribute(STATE_MESSAGE) == null) { if (state.getAttribute(STATE_IMPORT) != null) { // go to import tool page state.setAttribute(STATE_TEMPLATE_INDEX, "27"); } else if (goToToolConfigPage || ltiToolSelected) { state.setAttribute(STATE_MULTIPLE_TOOL_INSTANCE_SELECTED, Boolean.valueOf(goToToolConfigPage)); // go to the configuration page for multiple instances of tools state.setAttribute(STATE_TEMPLATE_INDEX, "26"); } else { // go to next page state.setAttribute(STATE_TEMPLATE_INDEX, continuePageIndex); } state.setAttribute(STATE_MULTIPLE_TOOL_ID_SET, multipleToolIdSet); state.setAttribute(STATE_MULTIPLE_TOOL_ID_TITLE_MAP, multipleToolIdTitleMap); } } // getFeatures /** * Import tools and content into the site * * If the isAddMissingToolsOnImportEnabled setting is true, tools that are selected for import and don't already exist in the target site will be added automatically. * * @param toolIds list of tools already in the site * @param importTools list of tools that were selected for import * @param site the site to import content into */ private void importToolIntoSite(List toolIds, Hashtable importTools, Site site) { if (importTools != null) { //if add missing tools is enabled, add the tools ito the site before importing content if (isAddMissingToolsOnImportEnabled()) { //add the toolId lists into a set to remove dupes Set<String> toolsToProcess = new HashSet<String>(toolIds); toolsToProcess.addAll(importTools.keySet()); //now compare what we have to what we need to add final List<String> selectedTools = new ArrayList<String>(toolsToProcess); M_log.debug("selectedTools: " + selectedTools); List<String> missingToolIds = new ArrayList<String>(selectedTools); missingToolIds.removeAll(toolIds); M_log.debug("missingToolIds: " + missingToolIds); //and add for (String missingToolId : missingToolIds) { site = addToolToSiteIfMissing(site, missingToolId); commitSite(site); } //now update toolIds to match importTools so that the content is imported toolIds.clear(); toolIds.addAll(importTools.keySet()); } Map transversalMap = new HashMap(); // import resources first boolean resourcesImported = false; for (int i = 0; i < toolIds.size() && !resourcesImported; i++) { String toolId = (String) toolIds.get(i); if (toolId.equalsIgnoreCase("sakai.resources") && importTools.containsKey(toolId)) { List importSiteIds = (List) importTools.get(toolId); for (int k = 0; k < importSiteIds.size(); k++) { String fromSiteId = (String) importSiteIds.get(k); String toSiteId = site.getId(); String fromSiteCollectionId = m_contentHostingService.getSiteCollection(fromSiteId); String toSiteCollectionId = m_contentHostingService.getSiteCollection(toSiteId); Map<String, String> entityMap = transferCopyEntities(toolId, fromSiteCollectionId, toSiteCollectionId); if (entityMap != null) { transversalMap.putAll(entityMap); } resourcesImported = true; } } } // import other tools then for (int i = 0; i < toolIds.size(); i++) { String toolId = (String) toolIds.get(i); if (!toolId.equalsIgnoreCase("sakai.resources") && importTools.containsKey(toolId)) { List importSiteIds = (List) importTools.get(toolId); for (int k = 0; k < importSiteIds.size(); k++) { String fromSiteId = (String) importSiteIds.get(k); String toSiteId = site.getId(); if (SITE_INFO_TOOL_ID.equals(toolId)) { copySiteInformation(fromSiteId, site); } else { Map<String, String> entityMap = transferCopyEntities(toolId, fromSiteId, toSiteId); if (entityMap != null) { transversalMap.putAll(entityMap); } resourcesImported = true; } } } } //update entity references for (int i = 0; i < toolIds.size(); i++) { String toolId = (String) toolIds.get(i); if (importTools.containsKey(toolId)) { List importSiteIds = (List) importTools.get(toolId); for (int k = 0; k < importSiteIds.size(); k++) { String toSiteId = site.getId(); updateEntityReferences(toolId, toSiteId, transversalMap, site); } } } } } private void importToolIntoSiteMigrate(List toolIds, Hashtable importTools, Site site) { if (importTools != null) { //if add missing tools is enabled, add the tools ito the site before importing content if (isAddMissingToolsOnImportEnabled()) { //add the toolId lists into a set to remove dupes Set<String> toolsToProcess = new HashSet<String>(toolIds); toolsToProcess.addAll(importTools.keySet()); //now compare what we have to what we need to add final List<String> selectedTools = new ArrayList<String>(toolsToProcess); M_log.debug("selectedTools: " + selectedTools); List<String> missingToolIds = new ArrayList<String>(selectedTools); missingToolIds.removeAll(toolIds); M_log.debug("missingToolIds: " + missingToolIds); //and add for (String missingToolId : missingToolIds) { site = addToolToSiteIfMissing(site, missingToolId); commitSite(site); } } Map transversalMap = new HashMap(); // import resources first boolean resourcesImported = false; for (int i = 0; i < toolIds.size() && !resourcesImported; i++) { String toolId = (String) toolIds.get(i); if (toolId.equalsIgnoreCase("sakai.resources") && importTools.containsKey(toolId)) { List importSiteIds = (List) importTools.get(toolId); for (int k = 0; k < importSiteIds.size(); k++) { String fromSiteId = (String) importSiteIds.get(k); String toSiteId = site.getId(); String fromSiteCollectionId = m_contentHostingService.getSiteCollection(fromSiteId); String toSiteCollectionId = m_contentHostingService.getSiteCollection(toSiteId); Map<String, String> entityMap = transferCopyEntitiesMigrate(toolId, fromSiteCollectionId, toSiteCollectionId); if (entityMap != null) { transversalMap.putAll(entityMap); } resourcesImported = true; } } } // import other tools then for (int i = 0; i < toolIds.size(); i++) { String toolId = (String) toolIds.get(i); if (!toolId.equalsIgnoreCase("sakai.resources") && importTools.containsKey(toolId)) { List importSiteIds = (List) importTools.get(toolId); for (int k = 0; k < importSiteIds.size(); k++) { String fromSiteId = (String) importSiteIds.get(k); String toSiteId = site.getId(); if (SITE_INFO_TOOL_ID.equals(toolId)) { copySiteInformation(fromSiteId, site); } else { Map<String, String> entityMap = transferCopyEntitiesMigrate(toolId, fromSiteId, toSiteId); if (entityMap != null) { transversalMap.putAll(entityMap); } } } } } //update entity references for (int i = 0; i < toolIds.size(); i++) { String toolId = (String) toolIds.get(i); if (importTools.containsKey(toolId)) { List importSiteIds = (List) importTools.get(toolId); for (int k = 0; k < importSiteIds.size(); k++) { String toSiteId = site.getId(); updateEntityReferences(toolId, toSiteId, transversalMap, site); } } } } } // importToolIntoSiteMigrate private void copySiteInformation(String fromSiteId, Site toSite) { try { Site fromSite = SiteService.getSite(fromSiteId); //we must get the new site again b/c some tools (lesson builder) can make changes to the site structure (i.e. add pages). Site editToSite = SiteService.getSite(toSite.getId()); editToSite.setDescription(fromSite.getDescription()); editToSite.setInfoUrl(fromSite.getInfoUrl()); commitSite(editToSite); toSite = editToSite; } catch (IdUnusedException e) { } } public void saveSiteStatus(SessionState state, boolean published) { Site site = getStateSite(state); site.setPublished(published); } // saveSiteStatus public void commitSite(Site site, boolean published) { site.setPublished(published); try { SiteService.save(site); } catch (IdUnusedException e) { // TODO: } catch (PermissionException e) { // TODO: } } // commitSite public void commitSite(Site site) { try { SiteService.save(site); } catch (IdUnusedException e) { // TODO: } catch (PermissionException e) { // TODO: } }// commitSite private String getSetupRequestEmailAddress() { String from = ServerConfigurationService.getString("setup.request", null); if (from == null) { from = "postmaster@".concat(ServerConfigurationService.getServerName()); M_log.warn(this + " - no 'setup.request' in configuration, using: " + from); } return from; } /** * get the setup.request.replyTo setting. If missing, use setup.request setting. * @return */ private String getSetupRequestReplyToEmailAddress() { String rv = ServerConfigurationService.getString("setup.request.replyTo", null); if (rv == null) { rv = getSetupRequestEmailAddress(); } return rv; } /** * addNewSite is called when the site has enough information to create a new * site * */ private void addNewSite(ParameterParser params, SessionState state) { if (getStateSite(state) != null) { // There is a Site in state already, so use it rather than creating // a new Site return; } // If cleanState() has removed SiteInfo, get a new instance into state SiteInfo siteInfo = new SiteInfo(); if (state.getAttribute(STATE_SITE_INFO) != null) { siteInfo = (SiteInfo) state.getAttribute(STATE_SITE_INFO); } String id = StringUtils.trimToNull(siteInfo.getSiteId()); if (id == null) { // get id id = IdManager.createUuid(); siteInfo.site_id = id; } state.setAttribute(STATE_SITE_INFO, siteInfo); if (state.getAttribute(STATE_MESSAGE) == null) { try { Site site = null; // if create based on template, Site templateSite = (Site) state.getAttribute(STATE_TEMPLATE_SITE); if (templateSite != null) { site = SiteService.addSite(id, templateSite); // set site type site.setType(SiteTypeUtil.getTargetSiteType(templateSite.getType())); } else { site = SiteService.addSite(id, siteInfo.site_type); } // add current user as the maintainer site.addMember(UserDirectoryService.getCurrentUser().getId(), site.getMaintainRole(), true, false); String title = StringUtils.trimToNull(siteInfo.title); String description = siteInfo.description; setAppearance(state, site, siteInfo.iconUrl); site.setDescription(description); if (title != null) { site.setTitle(title); } ResourcePropertiesEdit rp = site.getPropertiesEdit(); /// site language information String locale_string = (String) state.getAttribute("locale_string"); rp.addProperty(PROP_SITE_LANGUAGE, locale_string); site.setShortDescription(siteInfo.short_description); site.setPubView(siteInfo.include); site.setJoinable(siteInfo.joinable); site.setJoinerRole(siteInfo.joinerRole); site.setPublished(siteInfo.published); // site contact information rp.addProperty(Site.PROP_SITE_CONTACT_NAME, siteInfo.site_contact_name); rp.addProperty(Site.PROP_SITE_CONTACT_EMAIL, siteInfo.site_contact_email); // SAK-22790 add props from SiteInfo object rp.addAll(siteInfo.getProperties()); // SAK-23491 add template_used property if (templateSite != null) { // if the site was created from template rp.addProperty(TEMPLATE_USED, templateSite.getId()); } // bjones86 - SAK-24423 - update site properties for joinable site settings JoinableSiteSettings.updateSitePropertiesFromSiteInfoOnAddNewSite(siteInfo, rp); state.setAttribute(STATE_SITE_INSTANCE_ID, site.getId()); // commit newly added site in order to enable related realm commitSite(site); } catch (IdUsedException e) { addAlert(state, rb.getFormattedMessage("java.sitewithid.exists", new Object[] { id })); M_log.error(this + ".addNewSite: " + rb.getFormattedMessage("java.sitewithid.exists", new Object[] { id }), e); state.setAttribute(STATE_TEMPLATE_INDEX, params.getString("templateIndex")); return; } catch (IdInvalidException e) { addAlert(state, rb.getFormattedMessage("java.sitewithid.notvalid", new Object[] { id })); M_log.error(this + ".addNewSite: " + rb.getFormattedMessage("java.sitewithid.notvalid", new Object[] { id }), e); state.setAttribute(STATE_TEMPLATE_INDEX, params.getString("templateIndex")); return; } catch (PermissionException e) { addAlert(state, rb.getFormattedMessage("java.permission", new Object[] { id })); M_log.error(this + ".addNewSite: " + rb.getFormattedMessage("java.permission", new Object[] { id }), e); state.setAttribute(STATE_TEMPLATE_INDEX, params.getString("templateIndex")); return; } } } // addNewSite /** * created based on setTermListForContext - Denny * @param context * @param state */ private void setTemplateListForContext(Context context, SessionState state) { List<Site> templateSites = new ArrayList<Site>(); boolean allowedForTemplateSites = true; // system wide setting for disable site creation based on template sites if (ServerConfigurationService.getString("wsetup.enableSiteTemplate", "true") .equalsIgnoreCase(Boolean.FALSE.toString())) { allowedForTemplateSites = false; } else { if (ServerConfigurationService.getStrings("wsetup.enableSiteTemplate.userType") != null) { List<String> userTypes = new ArrayList( Arrays.asList(ServerConfigurationService.getStrings("wsetup.enableSiteTemplate.userType"))); if (userTypes != null && userTypes.size() > 0) { User u = UserDirectoryService.getCurrentUser(); if (!(u != null && (SecurityService.isSuperUser() || userTypes.contains(u.getType())))) { // be an admin type user or any type of users defined in the configuration allowedForTemplateSites = false; } } } } if (allowedForTemplateSites) { // We're searching for template sites and these are marked by a property // called 'template' with a value of true Map templateCriteria = new HashMap(1); templateCriteria.put("template", "true"); templateSites = SiteService.getSites(org.sakaiproject.site.api.SiteService.SelectionType.ANY, null, null, templateCriteria, SortType.TITLE_ASC, null); } // If no templates could be found, stick an empty list in the context if (templateSites == null || templateSites.size() <= 0) templateSites = new ArrayList(); //SAK25400 sort templates by type context.put("templateSites", sortTemplateSitesByType(templateSites)); context.put("titleMaxLength", state.getAttribute(STATE_SITE_TITLE_MAX)); } // setTemplateListForContext /** * %%% legacy properties, to be cleaned up * */ private void sitePropertiesIntoState(SessionState state) { try { Site site = getStateSite(state); SiteInfo siteInfo = new SiteInfo(); if (site != null) { ResourceProperties siteProperties = site.getProperties(); // set from site attributes siteInfo.title = site.getTitle(); siteInfo.description = site.getDescription(); siteInfo.iconUrl = site.getIconUrl(); siteInfo.infoUrl = site.getInfoUrl(); siteInfo.joinable = site.isJoinable(); siteInfo.joinerRole = site.getJoinerRole(); siteInfo.published = site.isPublished(); siteInfo.include = site.isPubView(); siteInfo.short_description = site.getShortDescription(); siteInfo.site_type = site.getType(); // term information String term = siteProperties.getProperty(Site.PROP_SITE_TERM); if (term != null) { siteInfo.term = term; } // bjones86 - SAK-24423 - update site info for joinable site settings JoinableSiteSettings.updateSiteInfoFromSiteProperties(siteProperties, siteInfo); // site contact information String contactName = siteProperties.getProperty(Site.PROP_SITE_CONTACT_NAME); String contactEmail = siteProperties.getProperty(Site.PROP_SITE_CONTACT_EMAIL); if (contactName == null && contactEmail == null) { User u = site.getCreatedBy(); if (u != null) { String email = u.getEmail(); if (email != null) { contactEmail = u.getEmail(); } contactName = u.getDisplayName(); } } if (contactName != null) { siteInfo.site_contact_name = contactName; } if (contactEmail != null) { siteInfo.site_contact_email = contactEmail; } state.setAttribute(FORM_SITEINFO_ALIASES, getSiteReferenceAliasIds(site)); } siteInfo.additional = ""; state.setAttribute(STATE_SITE_TYPE, siteInfo.site_type); state.setAttribute(STATE_SITE_INFO, siteInfo); state.setAttribute(FORM_SITEINFO_URL_BASE, getSiteBaseUrl()); } catch (Exception e) { M_log.error(this + ".sitePropertiesIntoState: " + e.getMessage(), e); } } // sitePropertiesIntoState /** * pageMatchesPattern returns tool id if a SitePage matches a WorkSite Setuppattern * otherwise return null * @param state * @param page * @return */ private List<String> pageMatchesPattern(SessionState state, SitePage page) { List<String> rv = new Vector<String>(); List pageToolList = page.getTools(); // if no tools on the page, return false if (pageToolList == null) { return null; } // don't compare tool properties, which may be changed using Options List toolList = new Vector(); int count = pageToolList.size(); // check Home tool first if (isHomePage(page)) { rv.add(TOOL_ID_HOME); rv.add(TOOL_ID_HOME); return rv; } // check whether the page has Site Info tool boolean foundSiteInfoTool = false; for (int i = 0; i < count; i++) { ToolConfiguration toolConfiguration = (ToolConfiguration) pageToolList.get(i); if (toolConfiguration.getToolId().equals(TOOL_ID_SITEINFO)) { foundSiteInfoTool = true; break; } } if (foundSiteInfoTool) { rv.add(TOOL_ID_SITEINFO); rv.add(TOOL_ID_SITEINFO); return rv; } // Other than Home, Site Info page, no other page is allowed to have more than one tool within. Otherwise, WSetup/Site Info tool won't handle it if (count != 1) { return null; } // if the page layout doesn't match, return false else if (page.getLayout() != SitePage.LAYOUT_SINGLE_COL) { return null; } else { // for the case where the page has one tool ToolConfiguration toolConfiguration = (ToolConfiguration) pageToolList.get(0); toolList = (List) state.getAttribute(STATE_TOOL_REGISTRATION_LIST); if (pageToolList != null && pageToolList.size() != 0) { // if tool attributes don't match, return false String match = null; for (ListIterator i = toolList.listIterator(); i.hasNext();) { MyTool tool = (MyTool) i.next(); if (toolConfiguration.getTitle() != null) { if (toolConfiguration.getTool() != null && originalToolId(toolConfiguration.getTool().getId(), tool.getId()) != null) { match = tool.getId(); rv.add(match); rv.add(toolConfiguration.getId()); } } } // no tool registeration is found (tool is not editable within Site Info tool), set return value to be null if (match == null) { rv = null; } } } return rv; } // pageMatchesPattern /** * check whether the page tool list contains certain toolId * @param pageToolList * @param toolId * @return */ private boolean pageHasToolId(List pageToolList, String toolId) { for (Iterator iPageToolList = pageToolList.iterator(); iPageToolList.hasNext();) { ToolConfiguration toolConfiguration = (ToolConfiguration) iPageToolList.next(); Tool t = toolConfiguration.getTool(); if (t != null && toolId.equals(toolConfiguration.getTool().getId())) { return true; } } return false; } /** * siteToolsIntoState is the replacement for siteToolsIntoState_ Make a list * of pages and tools that match WorkSite Setup configurations into state */ private void siteToolsIntoState(SessionState state) { // get the map of titles of multiple tool instances Map multipleToolIdTitleMap = state.getAttribute(STATE_MULTIPLE_TOOL_ID_TITLE_MAP) != null ? (Map) state.getAttribute(STATE_MULTIPLE_TOOL_ID_TITLE_MAP) : new HashMap(); Map<String, Map<String, String>> multipleToolIdAttributeMap = state .getAttribute(STATE_MULTIPLE_TOOL_CONFIGURATION) != null ? (Map<String, Map<String, String>>) state.getAttribute(STATE_MULTIPLE_TOOL_CONFIGURATION) : new HashMap(); String wSetupTool = NULL_STRING; String wSetupToolId = NULL_STRING; List wSetupPageList = new Vector(); Site site = getStateSite(state, true); List pageList = site.getPages(); // Put up tool lists filtered by category String type = checkNullSiteType(state, site.getType(), site.getId()); if (type == null) { M_log.warn(this + ": - unknown STATE_SITE_TYPE"); } else { state.setAttribute(STATE_SITE_TYPE, type); } // set tool registration list setToolRegistrationList(state, type); multipleToolIdAttributeMap = state.getAttribute(STATE_MULTIPLE_TOOL_CONFIGURATION) != null ? (Map<String, Map<String, String>>) state.getAttribute(STATE_MULTIPLE_TOOL_CONFIGURATION) : new HashMap(); // for the selected tools boolean check_home = false; Vector idSelected = new Vector(); HashMap<String, String> toolTitles = new HashMap<String, String>(); List toolRegList = (List) state.getAttribute(STATE_TOOL_REGISTRATION_LIST); // populate the tool title list if (toolRegList != null) { for (Object t : toolRegList) { toolTitles.put(((MyTool) t).getId(), ((MyTool) t).getTitle()); } } if (!((pageList == null) || (pageList.size() == 0))) { for (ListIterator i = pageList.listIterator(); i.hasNext();) { // reset wSetupTool = null; wSetupToolId = null; SitePage page = (SitePage) i.next(); // collect the pages consistent with Worksite Setup patterns List<String> pmList = pageMatchesPattern(state, page); if (pmList != null) { wSetupTool = pmList.get(0); wSetupToolId = pmList.get(1); } if (wSetupTool != null) { if (isHomePage(page)) { check_home = true; toolTitles.put("home", page.getTitle()); } else { if (isMultipleInstancesAllowed(findOriginalToolId(state, wSetupTool))) { String mId = page.getId() + wSetupTool; idSelected.add(mId); toolTitles.put(mId, page.getTitle()); multipleToolIdTitleMap.put(mId, page.getTitle()); // get the configuration for multiple instance HashMap<String, String> toolConfigurations = getMultiToolConfiguration(wSetupTool, page.getTool(wSetupToolId)); multipleToolIdAttributeMap.put(mId, toolConfigurations); MyTool newTool = new MyTool(); String titleConfig = ServerConfigurationService.getString(CONFIG_TOOL_TITLE + mId); if (titleConfig != null && titleConfig.length() > 0) { // check whether there is a different title setting newTool.title = titleConfig; } else { // use the default newTool.title = ToolManager.getTool(wSetupTool).getTitle(); } newTool.id = mId; newTool.selected = false; boolean hasThisMultipleTool = false; int j = 0; for (; j < toolRegList.size() && !hasThisMultipleTool; j++) { MyTool t = (MyTool) toolRegList.get(j); if (t.getId().equals(wSetupTool)) { hasThisMultipleTool = true; newTool.description = t.getDescription(); } } if (hasThisMultipleTool) { toolRegList.add(j - 1, newTool); } else { toolRegList.add(newTool); } } else { idSelected.add(wSetupTool); toolTitles.put(wSetupTool, page.getTitle()); } } WorksiteSetupPage wSetupPage = new WorksiteSetupPage(); wSetupPage.pageId = page.getId(); wSetupPage.pageTitle = page.getTitle(); wSetupPage.toolId = wSetupTool; wSetupPageList.add(wSetupPage); } } } state.setAttribute(STATE_MULTIPLE_TOOL_ID_TITLE_MAP, multipleToolIdTitleMap); state.setAttribute(STATE_MULTIPLE_TOOL_CONFIGURATION, multipleToolIdAttributeMap); state.setAttribute(STATE_TOOL_HOME_SELECTED, Boolean.valueOf(check_home)); state.setAttribute(STATE_TOOL_REGISTRATION_SELECTED_LIST, idSelected); // List state.setAttribute(STATE_TOOL_REGISTRATION_LIST, toolRegList); state.setAttribute(STATE_TOOL_REGISTRATION_TITLE_LIST, toolTitles); // of // ToolRegistration // toolId's state.setAttribute(STATE_TOOL_REGISTRATION_OLD_SELECTED_LIST, idSelected); // List of ToolRegistration toolId's state.setAttribute(STATE_TOOL_REGISTRATION_OLD_SELECTED_HOME, Boolean.valueOf(check_home)); state.setAttribute(STATE_WORKSITE_SETUP_PAGE_LIST, wSetupPageList); } // siteToolsIntoState /** * adjust site type * @param state * @param site * @return */ private String checkNullSiteType(SessionState state, String type, String siteId) { if (type == null) { if (siteId != null && SiteService.isUserSite(siteId)) { type = "myworkspace"; } else if (state.getAttribute(STATE_DEFAULT_SITE_TYPE) != null) { // for those sites without type, use the tool set for default // site type type = (String) state.getAttribute(STATE_DEFAULT_SITE_TYPE); } } return type; } /** * reset the state variables used in edit tools mode * * @state The SessionState object */ private void removeEditToolState(SessionState state) { state.removeAttribute(STATE_TOOL_HOME_SELECTED); state.removeAttribute(STATE_TOOL_REGISTRATION_SELECTED_LIST); // List // of // ToolRegistration // toolId's state.removeAttribute(STATE_TOOL_REGISTRATION_OLD_SELECTED_LIST); // List // of // ToolRegistration // toolId's state.removeAttribute(STATE_TOOL_REGISTRATION_OLD_SELECTED_HOME); state.removeAttribute(STATE_WORKSITE_SETUP_PAGE_LIST); state.removeAttribute(STATE_MULTIPLE_TOOL_ID_SET); state.removeAttribute(STATE_MULTIPLE_TOOL_ID_TITLE_MAP); state.removeAttribute(STATE_MULTIPLE_TOOL_CONFIGURATION); state.removeAttribute(STATE_TOOL_REGISTRATION_LIST); state.removeAttribute(STATE_TOOL_REGISTRATION_TITLE_LIST); state.removeAttribute(STATE_TOOL_REGISTRATION_SELECTED_LIST); MathJaxEnabler.removeMathJaxToolsAttributeFromState(state); // SAK-22384 } private List orderToolIds(SessionState state, String type, List<String> toolIdList, boolean synoptic) { List rv = new Vector(); // look for null site type if (type == null && state.getAttribute(STATE_DEFAULT_SITE_TYPE) != null) { type = (String) state.getAttribute(STATE_DEFAULT_SITE_TYPE); } if (type != null && toolIdList != null) { List<String> orderedToolIds = ServerConfigurationService .getToolOrder(SiteTypeUtil.getTargetSiteType(type)); // UMICH-1035 for (String tool_id : orderedToolIds) { for (String toolId : toolIdList) { String rToolId = originalToolId(toolId, tool_id); if (rToolId != null) { rv.add(toolId); break; } else { List<String> parentToolList = (List<String>) SYNOPTIC_TOOL_ID_MAP.get(toolId); if (parentToolList != null && parentToolList.contains(tool_id)) { rv.add(toolId); break; } } } } } // add those toolids without specified order if (toolIdList != null) { for (String toolId : toolIdList) { if (!rv.contains(toolId)) { rv.add(toolId); } } } return rv; } // orderToolIds private void setupFormNamesAndConstants(SessionState state) { TimeBreakdown timeBreakdown = (TimeService.newTime()).breakdownLocal(); String mycopyright = COPYRIGHT_SYMBOL + " " + timeBreakdown.getYear() + ", " + UserDirectoryService.getCurrentUser().getDisplayName() + ". All Rights Reserved. "; state.setAttribute(STATE_MY_COPYRIGHT, mycopyright); state.setAttribute(STATE_SITE_INSTANCE_ID, null); state.setAttribute(STATE_INITIALIZED, Boolean.TRUE.toString()); SiteInfo siteInfo = new SiteInfo(); Participant participant = new Participant(); participant.name = NULL_STRING; participant.uniqname = NULL_STRING; participant.active = true; state.setAttribute(STATE_SITE_INFO, siteInfo); state.setAttribute("form_participantToAdd", participant); state.setAttribute(FORM_ADDITIONAL, NULL_STRING); // legacy state.setAttribute(FORM_HONORIFIC, "0"); state.setAttribute(FORM_REUSE, "0"); state.setAttribute(FORM_RELATED_CLASS, "0"); state.setAttribute(FORM_RELATED_PROJECT, "0"); state.setAttribute(FORM_INSTITUTION, "0"); // sundry form variables state.setAttribute(FORM_PHONE, ""); state.setAttribute(FORM_EMAIL, ""); state.setAttribute(FORM_SUBJECT, ""); state.setAttribute(FORM_DESCRIPTION, ""); state.setAttribute(FORM_TITLE, ""); state.setAttribute(FORM_NAME, ""); state.setAttribute(FORM_SHORT_DESCRIPTION, ""); } // setupFormNamesAndConstants /** * setupSkins * */ private void setupIcons(SessionState state) { List icons = new Vector(); String[] iconNames = { "*default*" }; String[] iconUrls = { "" }; String[] iconSkins = { "" }; // get icon information if (ServerConfigurationService.getStrings("iconNames") != null) { iconNames = ServerConfigurationService.getStrings("iconNames"); } if (ServerConfigurationService.getStrings("iconUrls") != null) { iconUrls = ServerConfigurationService.getStrings("iconUrls"); } if (ServerConfigurationService.getStrings("iconSkins") != null) { iconSkins = ServerConfigurationService.getStrings("iconSkins"); } if ((iconNames != null) && (iconUrls != null) && (iconSkins != null) && (iconNames.length == iconUrls.length) && (iconNames.length == iconSkins.length)) { for (int i = 0; i < iconNames.length; i++) { MyIcon s = new MyIcon(StringUtils.trimToNull((String) iconNames[i]), StringUtils.trimToNull((String) iconUrls[i]), StringUtils.trimToNull((String) iconSkins[i])); icons.add(s); } } state.setAttribute(STATE_ICONS, icons); } private void setAppearance(SessionState state, Site edit, String iconUrl) { // set the icon iconUrl = StringUtils.trimToNull(iconUrl); //SAK-18721 convert spaces in URL to %20 iconUrl = StringUtils.replace(iconUrl, " ", "%20"); edit.setIconUrl(iconUrl); // if this icon is in the config appearance list, find a skin to set List icons = (List) state.getAttribute(STATE_ICONS); for (Iterator i = icons.iterator(); i.hasNext();) { Object icon = (Object) i.next(); if (icon instanceof MyIcon && StringUtils.equals(((MyIcon) icon).getUrl(), iconUrl)) { edit.setSkin(((MyIcon) icon).getSkin()); return; } } } /** * A dispatch funtion when selecting course features */ public void doAdd_features(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); ParameterParser params = data.getParameters(); String option = params.getString("option"); // to reset the state variable of the multiple tool instances Set multipleToolIdSet = state.getAttribute(STATE_MULTIPLE_TOOL_ID_SET) != null ? (Set) state.getAttribute(STATE_MULTIPLE_TOOL_ID_SET) : new HashSet(); // get the map of titles of multiple tool instances Map multipleToolIdTitleMap = state.getAttribute(STATE_MULTIPLE_TOOL_ID_TITLE_MAP) != null ? (Map) state.getAttribute(STATE_MULTIPLE_TOOL_ID_TITLE_MAP) : new HashMap(); // editing existing site or creating a new one? Site site = getStateSite(state); // dispatch if (option.startsWith("add_")) { // this could be format of originalToolId plus number of multiplication String addToolId = option.substring("add_".length(), option.length()); // find the original tool id String originToolId = findOriginalToolId(state, addToolId); if (originToolId != null) { Tool tool = ToolManager.getTool(originToolId); if (tool != null) { insertTool(state, originToolId, tool.getTitle(), tool.getDescription(), Integer.parseInt(params.getString("num_" + addToolId))); updateSelectedToolList(state, params, false); state.setAttribute(STATE_TEMPLATE_INDEX, "26"); } } } else if (option.startsWith("remove_")) { // this could be format of originalToolId plus number of multiplication String removeToolId = option.substring("remove_".length(), option.length()); // find the original tool id String originToolId = findOriginalToolId(state, removeToolId); if (originToolId != null) { Tool tool = ToolManager.getTool(originToolId); if (tool != null) { updateSelectedToolList(state, params, false); removeTool(state, removeToolId, originToolId); state.setAttribute(STATE_TEMPLATE_INDEX, "26"); } } } else if (option.equalsIgnoreCase("import")) { // import or not updateSelectedToolList(state, params, false); String importSites = params.getString("import"); if (importSites != null && importSites.equalsIgnoreCase(Boolean.TRUE.toString())) { state.setAttribute(STATE_IMPORT, Boolean.TRUE); if (importSites.equalsIgnoreCase(Boolean.TRUE.toString())) { state.removeAttribute(STATE_IMPORT); state.removeAttribute(STATE_IMPORT_SITES); state.removeAttribute(STATE_IMPORT_SITE_TOOL); } } else { state.removeAttribute(STATE_IMPORT); } } else if (option.equalsIgnoreCase("continueENW")) { // continue in multiple tools page updateSelectedToolList(state, params, false); doContinue(data); } else if (option.equalsIgnoreCase("continue")) { // continue MathJaxEnabler.applyToolSettingsToState(state, site, params); // SAK-22384 doContinue(data); } else if (option.equalsIgnoreCase("back")) { // back doBack(data); } else if (option.equalsIgnoreCase("cancel")) { if (site == null) { // cancel doCancel_create(data); } else { // cancel editing doCancel(data); } } } // doAdd_features /** * update the selected tool list * * @param params * The ParameterParser object * @param updateConfigVariables * Need to update configuration variables */ private void updateSelectedToolList(SessionState state, ParameterParser params, boolean updateConfigVariables) { if (params.getStrings("selectedTools") != null) { // read entries for multiple tool customization List selectedTools = new ArrayList(Arrays.asList(params.getStrings("selectedTools"))); HashMap<String, String> toolTitles = state.getAttribute(STATE_TOOL_REGISTRATION_TITLE_LIST) != null ? (HashMap<String, String>) state.getAttribute(STATE_TOOL_REGISTRATION_TITLE_LIST) : new HashMap<String, String>(); Set multipleToolIdSet = (Set) state.getAttribute(STATE_MULTIPLE_TOOL_ID_SET); Map multipleToolIdTitleMap = state.getAttribute(STATE_MULTIPLE_TOOL_ID_TITLE_MAP) != null ? (Map) state.getAttribute(STATE_MULTIPLE_TOOL_ID_TITLE_MAP) : new HashMap(); HashMap<String, HashMap<String, String>> multipleToolConfiguration = state .getAttribute(STATE_MULTIPLE_TOOL_CONFIGURATION) != null ? (HashMap<String, HashMap<String, String>>) state .getAttribute(STATE_MULTIPLE_TOOL_CONFIGURATION) : new HashMap<String, HashMap<String, String>>(); Vector<String> idSelected = (Vector<String>) state .getAttribute(STATE_TOOL_REGISTRATION_OLD_SELECTED_LIST); boolean has_home = false; String emailId = state.getAttribute(STATE_TOOL_EMAIL_ADDRESS) != null ? (String) state.getAttribute(STATE_TOOL_EMAIL_ADDRESS) : null; for (int i = 0; i < selectedTools.size(); i++) { String id = (String) selectedTools.get(i); if (id.equalsIgnoreCase(TOOL_ID_HOME)) { has_home = true; } else if (id.equalsIgnoreCase("sakai.mailbox")) { // read email id emailId = StringUtils.trimToNull(params.getString("emailId")); state.setAttribute(STATE_TOOL_EMAIL_ADDRESS, emailId); if (updateConfigVariables) { // if Email archive tool is selected, check the email alias String siteId = (String) state.getAttribute(STATE_SITE_INSTANCE_ID); String channelReference = mailArchiveChannelReference(siteId); if (emailId == null) { addAlert(state, rb.getString("java.emailarchive") + " "); } else { if (!Validator.checkEmailLocal(emailId)) { addAlert(state, rb.getString("java.theemail")); } else if (!aliasService.allowSetAlias(emailId, channelReference)) { addAlert(state, rb.getString("java.addalias")); } else { // check to see whether the alias has been used by // other sites try { String target = aliasService.getTarget(emailId); if (target != null) { if (siteId != null) { if (!target.equals(channelReference)) { // the email alias is not used by // current site addAlert(state, rb.getString("java.emailinuse") + " "); } } else { addAlert(state, rb.getString("java.emailinuse") + " "); } } } catch (IdUnusedException ee) { } } } } } else if (isMultipleInstancesAllowed(findOriginalToolId(state, id)) && (idSelected != null && !idSelected.contains(id) || idSelected == null)) { // newly added mutliple instances String title = StringUtils.trimToNull(params.getString("title_" + id)); if (title != null) { // truncate the title to maxlength as defined if (title.length() > MAX_TOOL_TITLE_LENGTH) { title = title.substring(0, MAX_TOOL_TITLE_LENGTH); } // save the titles entered multipleToolIdTitleMap.put(id, title); } toolTitles.put(id, title); // get the attribute input HashMap<String, String> attributes = multipleToolConfiguration.get(id); if (attributes == null) { // if missing, get the default setting for original id attributes = multipleToolConfiguration.get(findOriginalToolId(state, id)); } if (attributes != null) { for (Iterator<String> e = attributes.keySet().iterator(); e.hasNext();) { String attribute = e.next(); String attributeInput = StringUtils.trimToNull(params.getString(attribute + "_" + id)); if (attributeInput != null) { // save the attribute input if valid, otherwise generate alert if (FormattedText.validateURL(attributeInput)) attributes.put(attribute, attributeInput); else addAlert(state, rb.getString("java.invurl")); } } multipleToolConfiguration.put(id, attributes); } } } // update the state objects state.setAttribute(STATE_MULTIPLE_TOOL_ID_TITLE_MAP, multipleToolIdTitleMap); state.setAttribute(STATE_MULTIPLE_TOOL_CONFIGURATION, multipleToolConfiguration); state.setAttribute(STATE_TOOL_HOME_SELECTED, Boolean.valueOf(has_home)); state.setAttribute(STATE_TOOL_REGISTRATION_TITLE_LIST, toolTitles); } // read in the input for external tool list updateSelectedExternalToolList(state, params); } // updateSelectedToolList /** * read in the input for external tool list * @param state * @param params */ private void updateSelectedExternalToolList(SessionState state, ParameterParser params) { // update the lti tool list if (state.getAttribute(STATE_LTITOOL_SELECTED_LIST) != null) { Properties reqProps = params.getProperties(); // remember the reqProps may contain multiple lti inputs, so we need to differentiate those inputs and store one tool specific input into the map HashMap<String, Map<String, Object>> ltiTools = (HashMap<String, Map<String, Object>>) state .getAttribute(STATE_LTITOOL_SELECTED_LIST); for (Map.Entry<String, Map<String, Object>> ltiToolEntry : ltiTools.entrySet()) { String ltiToolId = ltiToolEntry.getKey(); Map<String, Object> ltiToolAttributes = ltiToolEntry.getValue(); String[] contentToolModel = m_ltiService.getContentModel(Long.valueOf(ltiToolId)); Properties reqForCurrentTool = new Properties(); // the input page contains attributes prefixed with lti tool id, need to look for those attribute inut values for (int k = 0; k < contentToolModel.length; k++) { // sample format of contentToolModel[k]: // title:text:label=bl_content_title:required=true:maxlength=255 String contentToolModelAttribute = contentToolModel[k].substring(0, contentToolModel[k].indexOf(":")); String k_contentToolModelAttribute = ltiToolId + "_" + contentToolModelAttribute; if (reqProps.containsKey(k_contentToolModelAttribute)) { reqForCurrentTool.put(contentToolModelAttribute, reqProps.get(k_contentToolModelAttribute)); } } // add the tool id field reqForCurrentTool.put(LTIService.LTI_TOOL_ID, ltiToolId); ltiToolAttributes.put("reqProperties", reqForCurrentTool); // update the lti tool list ltiTools.put(ltiToolId, ltiToolAttributes); } state.setAttribute(STATE_LTITOOL_SELECTED_LIST, ltiTools); } } /** * find the tool in the tool list and insert another tool instance to the list * @param state * @param toolId * @param defaultTitle * @param defaultDescription * @param insertTimes */ private void insertTool(SessionState state, String toolId, String defaultTitle, String defaultDescription, int insertTimes) { // the list of available tools List toolList = (List) state.getAttribute(STATE_TOOL_REGISTRATION_LIST); HashMap<String, String> toolTitles = state.getAttribute(STATE_TOOL_REGISTRATION_TITLE_LIST) != null ? (HashMap<String, String>) state.getAttribute(STATE_TOOL_REGISTRATION_TITLE_LIST) : new HashMap<String, String>(); List oTools = state.getAttribute(STATE_TOOL_REGISTRATION_OLD_SELECTED_LIST) == null ? new Vector() : (List) state.getAttribute(STATE_TOOL_REGISTRATION_OLD_SELECTED_LIST); // get the map of titles of multiple tool instances Map multipleToolIdTitleMap = state.getAttribute(STATE_MULTIPLE_TOOL_ID_TITLE_MAP) != null ? (Map) state.getAttribute(STATE_MULTIPLE_TOOL_ID_TITLE_MAP) : new HashMap(); // get the attributes of multiple tool instances HashMap<String, HashMap<String, String>> multipleToolConfiguration = state .getAttribute(STATE_MULTIPLE_TOOL_CONFIGURATION) != null ? (HashMap<String, HashMap<String, String>>) state .getAttribute(STATE_MULTIPLE_TOOL_CONFIGURATION) : new HashMap<String, HashMap<String, String>>(); int toolListedTimes = 0; // get the proper insert index for the whole tool list int index = 0; int insertIndex = 0; while (index < toolList.size()) { MyTool tListed = (MyTool) toolList.get(index); if (tListed.getId().indexOf(toolId) != -1 && !oTools.contains(tListed.getId())) { toolListedTimes++; // update the insert index insertIndex = index + 1; } index++; } // get the proper insert index for the selected tool list List toolSelected = (List) state.getAttribute(STATE_TOOL_REGISTRATION_SELECTED_LIST); index = 0; int insertSelectedToolIndex = 0; while (index < toolSelected.size()) { String selectedId = (String) toolSelected.get(index); if (selectedId.indexOf(toolId) != -1) { // update the insert index insertSelectedToolIndex = index + 1; } index++; } // insert multiple tools for (int i = 0; i < insertTimes; i++) { toolSelected.add(insertSelectedToolIndex, toolId + toolListedTimes); // We need to insert a specific tool entry only if all the specific // tool entries have been selected String newToolId = toolId + toolListedTimes; MyTool newTool = new MyTool(); String titleConfig = ServerConfigurationService.getString(CONFIG_TOOL_TITLE + toolId); if (titleConfig != null && titleConfig.length() > 0) { // check whether there is a different title setting defaultTitle = titleConfig; } newTool.title = defaultTitle; newTool.id = newToolId; newTool.description = defaultDescription; toolList.add(insertIndex, newTool); toolListedTimes++; // add title multipleToolIdTitleMap.put(newToolId, defaultTitle); toolTitles.put(newToolId, defaultTitle); // get the attribute input HashMap<String, String> attributes = multipleToolConfiguration.get(newToolId); if (attributes == null) { // if missing, get the default setting for original id attributes = getMultiToolConfiguration(toolId, null); multipleToolConfiguration.put(newToolId, attributes); } } state.setAttribute(STATE_MULTIPLE_TOOL_ID_TITLE_MAP, multipleToolIdTitleMap); state.setAttribute(STATE_MULTIPLE_TOOL_CONFIGURATION, multipleToolConfiguration); state.setAttribute(STATE_TOOL_REGISTRATION_LIST, toolList); state.setAttribute(STATE_TOOL_REGISTRATION_TITLE_LIST, toolTitles); state.setAttribute(STATE_TOOL_REGISTRATION_SELECTED_LIST, toolSelected); } // insertTool /** * find the tool in the tool list and remove the tool instance * @param state * @param toolId * @param originalToolId */ private void removeTool(SessionState state, String toolId, String originalToolId) { List toolList = (List) state.getAttribute(STATE_TOOL_REGISTRATION_LIST); // get the map of titles of multiple tool instances Map multipleToolIdTitleMap = state.getAttribute(STATE_MULTIPLE_TOOL_ID_TITLE_MAP) != null ? (Map) state.getAttribute(STATE_MULTIPLE_TOOL_ID_TITLE_MAP) : new HashMap(); // get the attributes of multiple tool instances HashMap<String, HashMap<String, String>> multipleToolConfiguration = state .getAttribute(STATE_MULTIPLE_TOOL_CONFIGURATION) != null ? (HashMap<String, HashMap<String, String>>) state .getAttribute(STATE_MULTIPLE_TOOL_CONFIGURATION) : new HashMap<String, HashMap<String, String>>(); // the selected tool list List toolSelected = (List) state.getAttribute(STATE_TOOL_REGISTRATION_SELECTED_LIST); // remove the tool from related state variables toolSelected.remove(toolId); // remove the tool from the title map multipleToolIdTitleMap.remove(toolId); // remove the tool from the configuration map boolean found = false; for (ListIterator i = toolList.listIterator(); i.hasNext() && !found;) { MyTool tool = (MyTool) i.next(); if (tool.getId().equals(toolId)) { toolList.remove(tool); found = true; } } multipleToolConfiguration.remove(toolId); state.setAttribute(STATE_MULTIPLE_TOOL_ID_TITLE_MAP, multipleToolIdTitleMap); state.setAttribute(STATE_MULTIPLE_TOOL_CONFIGURATION, multipleToolConfiguration); state.setAttribute(STATE_TOOL_REGISTRATION_LIST, toolList); state.setAttribute(STATE_TOOL_REGISTRATION_SELECTED_LIST, toolSelected); } // removeTool /** * * set selected participant role Hashtable */ private void setSelectedParticipantRoles(SessionState state) { List selectedUserIds = (List) state.getAttribute(STATE_SELECTED_USER_LIST); List participantList = collectionToList((Collection) state.getAttribute(STATE_PARTICIPANT_LIST)); List selectedParticipantList = new Vector(); Hashtable selectedParticipantRoles = new Hashtable(); if (!selectedUserIds.isEmpty() && participantList != null) { for (int i = 0; i < participantList.size(); i++) { String id = ""; Object o = (Object) participantList.get(i); if (o.getClass().equals(Participant.class)) { // get participant roles id = ((Participant) o).getUniqname(); selectedParticipantRoles.put(id, ((Participant) o).getRole()); } if (selectedUserIds.contains(id)) { selectedParticipantList.add(participantList.get(i)); } } } state.setAttribute(STATE_SELECTED_PARTICIPANT_ROLES, selectedParticipantRoles); state.setAttribute(STATE_SELECTED_PARTICIPANTS, selectedParticipantList); } // setSelectedParticipantRol3es public class MyIcon { protected String m_name = null; protected String m_url = null; protected String m_skin = null; public MyIcon(String name, String url, String skin) { m_name = name; m_url = url; m_skin = skin; } public String getName() { return m_name; } public String getUrl() { return m_url; } public String getSkin() { return m_skin; } } // a utility class for working with ToolConfigurations and ToolRegistrations // %%% convert featureList from IdAndText to Tool so getFeatures item.id = // chosen-feature.id is a direct mapping of data public class MyTool { public String id = NULL_STRING; public String title = NULL_STRING; public String description = NULL_STRING; public boolean selected = false; public boolean multiple = false; public String group = NULL_STRING; public String moreInfo = NULL_STRING; public HashMap<String, MyTool> multiples = new HashMap<String, MyTool>(); public boolean required = false; public String getId() { return id; } public String getTitle() { return title; } public String getDescription() { return description; } public boolean getSelected() { return selected; } public boolean isRequired() { return required; } public boolean hasMultiples() { return multiple; } public String getGroup() { return group; } public String getMoreInfo() { return moreInfo; } // SAK-16600 public HashMap<String, MyTool> getMultiples(String toolId) { if (multiples == null) { return new HashMap<String, MyTool>(); } else { return multiples; } } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + getOuterType().hashCode(); result = prime * result + ((id == null) ? 0 : id.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; MyTool other = (MyTool) obj; if (!getOuterType().equals(other.getOuterType())) return false; if (id == null) { if (other.id != null) return false; } else if (!id.equals(other.id)) return false; return true; } private SiteAction getOuterType() { return SiteAction.this; } } /* * WorksiteSetupPage is a utility class for working with site pages * configured by Worksite Setup * */ public class WorksiteSetupPage { public String pageId = NULL_STRING; public String pageTitle = NULL_STRING; public String toolId = NULL_STRING; public String getPageId() { return pageId; } public String getPageTitle() { return pageTitle; } public String getToolId() { return toolId; } } // WorksiteSetupPage public class SiteInfo { public String site_id = NULL_STRING; // getId of Resource public String external_id = NULL_STRING; // if matches site_id // connects site with U-M // course information public String site_type = ""; public String iconUrl = NULL_STRING; public String infoUrl = NULL_STRING; public boolean joinable = false; public Set<String> additionalRoles = Collections.EMPTY_SET; public String joinerRole = NULL_STRING; public String title = NULL_STRING; // the short name of the site public Set<String> siteRefAliases = new HashSet<String>(); // the aliases for the site itself public String short_description = NULL_STRING; // the short (20 char) // description of the // site public String description = NULL_STRING; // the longer description of // the site public String additional = NULL_STRING; // additional information on // crosslists, etc. public boolean published = false; public boolean include = true; // include the site in the Sites index; // default is true. public String site_contact_name = NULL_STRING; // site contact name public String site_contact_email = NULL_STRING; // site contact email public String term = NULL_STRING; // academic term public ResourceProperties properties = new BaseResourcePropertiesEdit(); // bjones86 - SAK-24423 - joinable site settings public String joinerGroup = NULL_STRING; public String getJoinerGroup() { return joinerGroup; } public boolean joinExcludePublic = false; public boolean getJoinExcludePublic() { return joinExcludePublic; } public boolean joinLimitByAccountType = false; public boolean getJoinLimitByAccountType() { return joinLimitByAccountType; } public String joinLimitedAccountTypes = NULL_STRING; public String getJoinLimitedAccountTypes() { return joinLimitedAccountTypes; } // end joinable site settings public String getSiteId() { return site_id; } public String getSiteType() { return site_type; } public String getTitle() { return title; } public String getDescription() { return description; } public String getIconUrl() { return iconUrl; } public String getInfoUrll() { return infoUrl; } public boolean getJoinable() { return joinable; } public String getJoinerRole() { return joinerRole; } public String getAdditional() { return additional; } public boolean getPublished() { return published; } public boolean getInclude() { return include; } public String getSiteContactName() { return site_contact_name; } public String getSiteContactEmail() { return site_contact_email; } public String getFirstAlias() { return siteRefAliases.isEmpty() ? NULL_STRING : siteRefAliases.iterator().next(); } public void addProperty(String key, String value) { properties.addProperty(key, value); } public ResourceProperties getProperties() { return properties; } public Set<String> getSiteRefAliases() { return siteRefAliases; } public void setSiteRefAliases(Set<String> siteRefAliases) { this.siteRefAliases = siteRefAliases; } public String getTerm() { return term; } public void setTerm(String term) { this.term = term; } } // SiteInfo public class AdditionalRoleGroup implements Comparable<AdditionalRoleGroup> { public String name; public List<AdditionalRole> roles; public AdditionalRoleGroup(String name) { this.name = name; this.roles = new ArrayList<AdditionalRole>(); } public String getName() { return name; } public List<AdditionalRole> getRoles() { return roles; } public int getSize() { return roles.size(); } @Override public int compareTo(AdditionalRoleGroup arg0) { if (arg0 == null) return 1; if (this.name == null && arg0.name == null) return 0; if (this.name == null || arg0.name == null) return (this.name == null) ? -1 : 1; return this.name.compareTo(arg0.name); } } public class AdditionalRole implements Comparable<AdditionalRole> { public String id; public String name; public boolean editable; public boolean granted; public String getId() { return id; } public String getName() { return name; } public boolean isEditable() { return editable; } public boolean isGranted() { return granted; } @Override public int compareTo(AdditionalRole arg0) { if (arg0 == null) return 1; if (this.name == null && arg0.name == null) return 0; if (this.name == null || arg0.name == null) return (this.name == null) ? -1 : 1; return this.name.compareTo(arg0.name); } } // customized type tool related /** * doFinish_site_type_tools is called when creation of a customized type site is * confirmed */ public void doFinish_site_type_tools(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); ParameterParser params = data.getParameters(); // set up for the coming template state.setAttribute(STATE_TEMPLATE_INDEX, params.getString("continue")); int index = Integer.valueOf(params.getString("templateIndex")).intValue(); actionForTemplate("continue", index, params, state, data); // add the pre-configured site type tools to a new site addSiteTypeFeatures(state); // TODO: hard coding this frame id is fragile, portal dependent, and // needs to be fixed -ggolden // schedulePeerFrameRefresh("sitenav"); scheduleTopRefresh(); resetPaging(state); }// doFinish_site-type_tools /** * addSiteTypeToolsFeatures adds features to a new customized type site * */ private void addSiteTypeFeatures(SessionState state) { Site edit = null; Site template = null; String type = (String) state.getAttribute(STATE_SITE_TYPE); HashMap<String, String> templates = siteTypeProvider.getTemplateForSiteTypes(); // get the template site id for this site type if (templates != null && templates.containsKey(type)) { String templateId = templates.get(type); // get a unique id String id = IdManager.createUuid(); // get the site template try { template = SiteService.getSite(templateId); } catch (Exception e) { M_log.error(this + ".addSiteTypeFeatures:" + e.getMessage() + templateId, e); } if (template != null) { // create a new site based on the template try { edit = SiteService.addSite(id, template); // set site type edit.setType(SiteTypeUtil.getTargetSiteType(template.getType())); } catch (Exception e) { M_log.error(this + ".addSiteTypeFeatures:" + " add/edit site id=" + id, e); } // set the tab, etc. if (edit != null) { SiteInfo siteInfo = (SiteInfo) state.getAttribute(STATE_SITE_INFO); edit.setShortDescription(siteInfo.short_description); edit.setTitle(siteInfo.title); edit.setPublished(true); edit.setPubView(false); // SAK-23491 add template_used property edit.getPropertiesEdit().addProperty(TEMPLATE_USED, templateId); try { SiteService.save(edit); } catch (Exception e) { M_log.error(this + ".addSiteTypeFeatures:" + " commitEdit site id=" + id, e); } // now that the site and realm exist, we can set the email alias // set the site alias as: User currentUser = UserDirectoryService.getCurrentUser(); List<String> pList = new ArrayList<String>(); pList.add(currentUser != null ? currentUser.getEid() : ""); String alias = siteTypeProvider.getSiteAlias(type, pList); String channelReference = mailArchiveChannelReference(id); try { aliasService.setAlias(alias, channelReference); } catch (IdUsedException ee) { addAlert(state, rb.getFormattedMessage("java.alias.exists", new Object[] { alias })); M_log.error(this + ".addSiteTypeFeatures:" + rb.getFormattedMessage("java.alias.exists", new Object[] { alias }), ee); } catch (IdInvalidException ee) { addAlert(state, rb.getFormattedMessage("java.alias.isinval", new Object[] { alias })); M_log.error(this + ".addSiteTypeFeatures:" + rb.getFormattedMessage("java.alias.isinval", new Object[] { alias }), ee); } catch (PermissionException ee) { addAlert(state, rb.getString("java.addalias")); M_log.error(this + ".addSiteTypeFeatures:" + SessionManager.getCurrentSessionUserId() + " does not have permission to add alias. ", ee); } } } } } // addSiteTypeFeatures /** * handle with add site options * */ public void doAdd_site_option(RunData data) { String option = data.getParameters().getString("option"); if ("finish".equals(option)) { SessionState state = ((JetspeedRunData) data) .getPortletSessionState(((JetspeedRunData) data).getJs_peid()); Site site = getStateSite(state); if (site == null) { doFinish(data); } else // There is a site in the state already, likely from a previous request that is still processing { // Abort this request to prevent adding multiple copies of tools to the same site. String msg = "Detected request to create a site while site %s already exists in current session state. Aborting request."; if (M_log.isDebugEnabled()) { M_log.debug(String.format(msg, StringUtils.trimToEmpty(site.getId()))); } } } else if ("cancel".equals(option)) { doCancel_create(data); } else if ("back".equals(option)) { doBack(data); } } // doAdd_site_option /** * handle with duplicate site options * */ public void doDuplicate_site_option(RunData data) { String option = data.getParameters().getString("option"); if ("duplicate".equals(option)) { doContinue(data); } else if ("cancel".equals(option)) { doCancel(data); } else if ("finish".equals(option)) { doContinue(data); } } // doDuplicate_site_option /** * Get the mail archive channel reference for the main container placement * for this site. * * @param siteId * The site id. * @return The mail archive channel reference for this site. */ protected String mailArchiveChannelReference(String siteId) { Object m = ComponentManager.get("org.sakaiproject.mailarchive.api.MailArchiveService"); if (m != null) { return "/mailarchive" + Entity.SEPARATOR + "channel" + Entity.SEPARATOR + siteId + Entity.SEPARATOR + SiteService.MAIN_CONTAINER; } else { return ""; } } /** * Transfer a copy of all entites from another context for any entity * producer that claims this tool id. * * @param toolId * The tool id. * @param fromContext * The context to import from. * @param toContext * The context to import into. */ protected Map transferCopyEntities(String toolId, String fromContext, String toContext) { // TODO: used to offer to resources first - why? still needed? -ggolden Map transversalMap = new HashMap(); // offer to all EntityProducers for (Iterator i = EntityManager.getEntityProducers().iterator(); i.hasNext();) { EntityProducer ep = (EntityProducer) i.next(); if (ep instanceof EntityTransferrer) { try { EntityTransferrer et = (EntityTransferrer) ep; // if this producer claims this tool id if (ArrayUtil.contains(et.myToolIds(), toolId)) { if (ep instanceof EntityTransferrerRefMigrator) { EntityTransferrerRefMigrator etMp = (EntityTransferrerRefMigrator) ep; Map<String, String> entityMap = etMp.transferCopyEntitiesRefMigrator(fromContext, toContext, new Vector()); if (entityMap != null) { transversalMap.putAll(entityMap); } } else { et.transferCopyEntities(fromContext, toContext, new Vector()); } } } catch (Throwable t) { M_log.error(this + ".transferCopyEntities: Error encountered while asking EntityTransfer to transferCopyEntities from: " + fromContext + " to: " + toContext, t); } } } // record direct URL for this tool in old and new sites, so anyone using the URL in HTML text will // get a proper update for the HTML in the new site // Some tools can have more than one instance. Because getTools should always return tools // in order, we can assume that if there's more than one instance of a tool, the instances // correspond Site fromSite = null; Site toSite = null; Collection<ToolConfiguration> fromTools = null; Collection<ToolConfiguration> toTools = null; try { fromSite = SiteService.getSite(fromContext); toSite = SiteService.getSite(toContext); fromTools = fromSite.getTools(toolId); toTools = toSite.getTools(toolId); } catch (Exception e) { M_log.warn(this + "transferCopyEntities: can't get site:" + e.getMessage()); } // getTools appears to return tools in order. So we should be able to match them if (fromTools != null && toTools != null) { Iterator<ToolConfiguration> toToolIt = toTools.iterator(); // step through tools in old and new site in parallel // I believe the first time this is called for a given // tool all instances will be copied, but stop if not // all instances have been copied yet for (ToolConfiguration fromTool : fromTools) { if (toToolIt.hasNext()) { ToolConfiguration toTool = toToolIt.next(); String fromUrl = ServerConfigurationService.getPortalUrl() + "/directtool/" + Web.escapeUrl(fromTool.getId()) + "/"; String toUrl = ServerConfigurationService.getPortalUrl() + "/directtool/" + Web.escapeUrl(toTool.getId()) + "/"; if (transversalMap.get(fromUrl) == null) transversalMap.put(fromUrl, toUrl); if (shortenedUrlService.shouldCopy(fromUrl)) { fromUrl = shortenedUrlService.shorten(fromUrl, false); toUrl = shortenedUrlService.shorten(toUrl, false); if (fromUrl != null && toUrl != null) transversalMap.put(fromUrl, toUrl); } } else break; } } return transversalMap; } private void updateSiteInfoToolEntityReferences(Map transversalMap, Site newSite) { if (transversalMap != null && transversalMap.size() > 0 && newSite != null) { Set<Entry<String, String>> entrySet = (Set<Entry<String, String>>) transversalMap.entrySet(); String msgBody = newSite.getDescription(); if (msgBody != null && !"".equals(msgBody)) { boolean updated = false; Iterator<Entry<String, String>> entryItr = entrySet.iterator(); while (entryItr.hasNext()) { Entry<String, String> entry = (Entry<String, String>) entryItr.next(); String fromContextRef = entry.getKey(); if (msgBody.contains(fromContextRef)) { msgBody = msgBody.replace(fromContextRef, entry.getValue()); updated = true; } } if (updated) { //update the site b/c some tools (Lessonbuilder) updates the site structure (add/remove pages) and we don't want to //over write this try { newSite = SiteService.getSite(newSite.getId()); newSite.setDescription(msgBody); SiteService.save(newSite); } catch (IdUnusedException e) { // TODO: } catch (PermissionException e) { // TODO: } } } } } protected void updateEntityReferences(String toolId, String toContext, Map transversalMap, Site newSite) { if (toolId.equalsIgnoreCase(SITE_INFORMATION_TOOL)) { updateSiteInfoToolEntityReferences(transversalMap, newSite); } else { for (Iterator i = EntityManager.getEntityProducers().iterator(); i.hasNext();) { EntityProducer ep = (EntityProducer) i.next(); if (ep instanceof EntityTransferrerRefMigrator && ep instanceof EntityTransferrer) { try { EntityTransferrer et = (EntityTransferrer) ep; EntityTransferrerRefMigrator etRM = (EntityTransferrerRefMigrator) ep; // if this producer claims this tool id if (ArrayUtil.contains(et.myToolIds(), toolId)) { etRM.updateEntityReferences(toContext, transversalMap); } } catch (Throwable t) { M_log.error( "Error encountered while asking EntityTransfer to updateEntityReferences at site: " + toContext, t); } } } } } protected Map transferCopyEntitiesMigrate(String toolId, String fromContext, String toContext) { Map transversalMap = new HashMap(); for (Iterator i = EntityManager.getEntityProducers().iterator(); i.hasNext();) { EntityProducer ep = (EntityProducer) i.next(); if (ep instanceof EntityTransferrer) { try { EntityTransferrer et = (EntityTransferrer) ep; // if this producer claims this tool id if (ArrayUtil.contains(et.myToolIds(), toolId)) { if (ep instanceof EntityTransferrerRefMigrator) { EntityTransferrerRefMigrator etRM = (EntityTransferrerRefMigrator) ep; Map<String, String> entityMap = etRM.transferCopyEntitiesRefMigrator(fromContext, toContext, new Vector(), true); if (entityMap != null) { transversalMap.putAll(entityMap); } } else { et.transferCopyEntities(fromContext, toContext, new Vector(), true); } } } catch (Throwable t) { M_log.error("Error encountered while asking EntityTransfer to transferCopyEntities from: " + fromContext + " to: " + toContext, t); } } } return transversalMap; } /** * @return Get a list of all tools that support the import (transfer copy) * option */ protected Set importTools() { HashSet rv = new HashSet(); // offer to all EntityProducers for (Iterator i = EntityManager.getEntityProducers().iterator(); i.hasNext();) { EntityProducer ep = (EntityProducer) i.next(); if (ep instanceof EntityTransferrer) { EntityTransferrer et = (EntityTransferrer) ep; String[] tools = et.myToolIds(); if (tools != null) { for (int t = 0; t < tools.length; t++) { rv.add(tools[t]); } } } } if (ServerConfigurationService.getBoolean("site-manage.importoption.siteinfo", false)) { rv.add(SITE_INFO_TOOL_ID); } return rv; } /** * @param state * @return Get a list of all tools that should be included as options for * import */ protected List getToolsAvailableForImport(SessionState state, List<String> toolIdList) { // The Web Content and News tools do not follow the standard rules for // import // Even if the current site does not contain the tool, News and WC will // be // an option if the imported site contains it boolean displayWebContent = false; boolean displayNews = false; boolean displayLessons = false; Set importSites = ((Hashtable) state.getAttribute(STATE_IMPORT_SITES)).keySet(); Iterator sitesIter = importSites.iterator(); while (sitesIter.hasNext()) { Site site = (Site) sitesIter.next(); // web content is a little tricky because worksite setup has the same tool id. you // can differentiate b/c worksite setup has a property with the key "special" Collection iframeTools = new ArrayList<Tool>(); iframeTools = site.getTools(new String[] { WEB_CONTENT_TOOL_ID }); if (iframeTools != null && iframeTools.size() > 0) { for (Iterator i = iframeTools.iterator(); i.hasNext();) { ToolConfiguration tool = (ToolConfiguration) i.next(); if (!tool.getPlacementConfig().containsKey("special")) { displayWebContent = true; } } } if (site.getToolForCommonId(NEWS_TOOL_ID) != null) displayNews = true; if (site.getToolForCommonId(LESSONS_TOOL_ID) != null) displayLessons = true; } if (displayWebContent && !toolIdList.contains(WEB_CONTENT_TOOL_ID)) toolIdList.add(WEB_CONTENT_TOOL_ID); if (displayNews && !toolIdList.contains(NEWS_TOOL_ID)) toolIdList.add(NEWS_TOOL_ID); if (displayLessons && !toolIdList.contains(LESSONS_TOOL_ID)) toolIdList.add(LESSONS_TOOL_ID); if (ServerConfigurationService.getBoolean("site-manage.importoption.siteinfo", false)) { toolIdList.add(SITE_INFO_TOOL_ID); } return toolIdList; } // getToolsAvailableForImport // bjones86 - SAK-23256 - added userFilteringIfEnabled parameter private List<AcademicSession> setTermListForContext(Context context, SessionState state, boolean upcomingOnly, boolean useFilteringIfEnabled) { List<AcademicSession> terms; if (upcomingOnly) { terms = cms != null ? cms.getCurrentAcademicSessions() : null; } else { // get all terms = cms != null ? cms.getAcademicSessions() : null; } if (terms != null && terms.size() > 0) { // bjones86 - SAK-23256 if (useFilteringIfEnabled) { if (!SecurityService.isSuperUser()) { if (ServerConfigurationService.getBoolean(SAK_PROP_FILTER_TERMS, false)) { terms = filterTermDropDowns(); } } } context.put("termList", sortAcademicSessions(terms)); } return terms; } // setTermListForContext private void setSelectedTermForContext(Context context, SessionState state, String stateAttribute) { if (state.getAttribute(stateAttribute) != null) { context.put("selectedTerm", state.getAttribute(stateAttribute)); } } // setSelectedTermForContext /** * Removes any academic sessions that the user is not currently enrolled in * * @author bjones86 - SAK-23256 * * @return the filtered list of academic sessions */ public List<AcademicSession> filterTermDropDowns() { List<AcademicSession> academicSessions = new ArrayList<AcademicSession>(); User user = UserDirectoryService.getCurrentUser(); if (cms != null && user != null) { Map<String, String> sectionRoles = cms.findSectionRoles(user.getEid()); if (sectionRoles != null) { // Iterate through all the sections and add their corresponding academic sessions to our return value Set<String> sectionEids = sectionRoles.keySet(); Iterator<String> itr = sectionEids.iterator(); while (itr.hasNext()) { String sectionEid = itr.next(); Section section = cms.getSection(sectionEid); if (section != null) { CourseOffering courseOffering = cms.getCourseOffering(section.getCourseOfferingEid()); if (courseOffering != null) { academicSessions.add(courseOffering.getAcademicSession()); } } } } } // Remove duplicates for (int i = 0; i < academicSessions.size(); i++) { for (int j = i + 1; j < academicSessions.size(); j++) { if (academicSessions.get(i).getEid().equals(academicSessions.get(j).getEid())) { academicSessions.remove(academicSessions.get(j)); j--; //stay on this index (ie. j will get incremented back) } } } return academicSessions; } /** * rewrote for 2.4 * * @param userId * @param academicSessionEid * @param courseOfferingHash * @param sectionHash */ private void prepareCourseAndSectionMap(String userId, String academicSessionEid, HashMap courseOfferingHash, HashMap sectionHash) { // looking for list of courseOffering and sections that should be // included in // the selection list. The course offering must be offered // 1. in the specific academic Session // 2. that the specified user has right to attach its section to a // course site // map = (section.eid, sakai rolename) if (groupProvider == null) { M_log.warn("Group provider not found"); return; } Map map = groupProvider.getGroupRolesForUser(userId); if (map == null) return; Set keys = map.keySet(); Set roleSet = getRolesAllowedToAttachSection(); for (Iterator i = keys.iterator(); i.hasNext();) { String sectionEid = (String) i.next(); String role = (String) map.get(sectionEid); if (includeRole(role, roleSet)) { Section section = null; getCourseOfferingAndSectionMap(academicSessionEid, courseOfferingHash, sectionHash, sectionEid, section); } } // now consider those user with affiliated sections List affiliatedSectionEids = affiliatedSectionProvider.getAffiliatedSectionEids(userId, academicSessionEid); if (affiliatedSectionEids != null) { for (int k = 0; k < affiliatedSectionEids.size(); k++) { String sectionEid = (String) affiliatedSectionEids.get(k); Section section = null; getCourseOfferingAndSectionMap(academicSessionEid, courseOfferingHash, sectionHash, sectionEid, section); } } } // prepareCourseAndSectionMap private void getCourseOfferingAndSectionMap(String academicSessionEid, HashMap courseOfferingHash, HashMap sectionHash, String sectionEid, Section section) { try { section = cms.getSection(sectionEid); } catch (IdNotFoundException e) { M_log.warn("getCourseOfferingAndSectionMap: cannot find section " + sectionEid); } if (section != null) { String courseOfferingEid = section.getCourseOfferingEid(); CourseOffering courseOffering = cms.getCourseOffering(courseOfferingEid); String sessionEid = courseOffering.getAcademicSession().getEid(); if (academicSessionEid.equals(sessionEid)) { // a long way to the conclusion that yes, this course // offering // should be included in the selected list. Sigh... // -daisyf ArrayList sectionList = (ArrayList) sectionHash.get(courseOffering.getEid()); if (sectionList == null) { sectionList = new ArrayList(); } sectionList.add(new SectionObject(section)); sectionHash.put(courseOffering.getEid(), sectionList); courseOfferingHash.put(courseOffering.getEid(), courseOffering); } } } /** * for 2.4 * * @param role * @return */ private boolean includeRole(String role, Set roleSet) { boolean includeRole = false; for (Iterator i = roleSet.iterator(); i.hasNext();) { String r = (String) i.next(); if (r.equals(role)) { includeRole = true; break; } } return includeRole; } // includeRole protected Set getRolesAllowedToAttachSection() { // Use !site.template.[site_type] String azgId = "!site.template.course"; AuthzGroup azgTemplate; try { azgTemplate = authzGroupService.getAuthzGroup(azgId); } catch (GroupNotDefinedException e) { M_log.error(this + ".getRolesAllowedToAttachSection: Could not find authz group " + azgId, e); return new HashSet(); } Set roles = azgTemplate.getRolesIsAllowed("site.upd"); roles.addAll(azgTemplate.getRolesIsAllowed("realm.upd")); return roles; } // getRolesAllowedToAttachSection /** * Here, we will preapre two HashMap: 1. courseOfferingHash stores * courseOfferingId and CourseOffering 2. sectionHash stores * courseOfferingId and a list of its Section We sorted the CourseOffering * by its eid & title and went through them one at a time to construct the * CourseObject that is used for the displayed in velocity. Each * CourseObject will contains a list of CourseOfferingObject(again used for * vm display). Usually, a CourseObject would only contain one * CourseOfferingObject. A CourseObject containing multiple * CourseOfferingObject implies that this is a cross-listing situation. * * @param userId * @param academicSessionEid * @return */ private List prepareCourseAndSectionListing(String userId, String academicSessionEid, SessionState state) { // courseOfferingHash = (courseOfferingEid, vourseOffering) // sectionHash = (courseOfferingEid, list of sections) HashMap courseOfferingHash = new HashMap(); HashMap sectionHash = new HashMap(); prepareCourseAndSectionMap(userId, academicSessionEid, courseOfferingHash, sectionHash); // courseOfferingHash & sectionHash should now be filled with stuffs // put section list in state for later use state.setAttribute(STATE_PROVIDER_SECTION_LIST, getSectionList(sectionHash)); ArrayList offeringList = new ArrayList(); Set keys = courseOfferingHash.keySet(); for (Iterator i = keys.iterator(); i.hasNext();) { CourseOffering o = (CourseOffering) courseOfferingHash.get((String) i.next()); offeringList.add(o); } Collection offeringListSorted = sortCourseOfferings(offeringList); ArrayList resultedList = new ArrayList(); // use this to keep track of courseOffering that we have dealt with // already // this is important 'cos cross-listed offering is dealt with together // with its // equivalents ArrayList dealtWith = new ArrayList(); for (Iterator j = offeringListSorted.iterator(); j.hasNext();) { CourseOffering o = (CourseOffering) j.next(); if (!dealtWith.contains(o.getEid())) { // 1. construct list of CourseOfferingObject for CourseObject ArrayList l = new ArrayList(); CourseOfferingObject coo = new CourseOfferingObject(o, (ArrayList) sectionHash.get(o.getEid())); l.add(coo); // 2. check if course offering is cross-listed Set set = cms.getEquivalentCourseOfferings(o.getEid()); if (set != null) { for (Iterator k = set.iterator(); k.hasNext();) { CourseOffering eo = (CourseOffering) k.next(); if (courseOfferingHash.containsKey(eo.getEid())) { // => cross-listed, then list them together CourseOfferingObject coo_equivalent = new CourseOfferingObject(eo, (ArrayList) sectionHash.get(eo.getEid())); l.add(coo_equivalent); dealtWith.add(eo.getEid()); } } } CourseObject co = new CourseObject(o, l); dealtWith.add(o.getEid()); resultedList.add(co); } } return resultedList; } // prepareCourseAndSectionListing /* SAK-25400 template site types duplicated in list * Sort template sites by type **/ private Collection sortTemplateSitesByType(Collection<Site> templates) { String[] sortKey = { "type" }; String[] sortOrder = { "asc" }; return sortCmObject(templates, sortKey, sortOrder); } /** * Helper method for sortCmObject * by order from sakai properties if specified or * by default of eid, title * using velocity SortTool * * @param offerings * @return */ private Collection sortCourseOfferings(Collection<CourseOffering> offerings) { // Get the keys from sakai.properties String[] keys = ServerConfigurationService.getStrings(SORT_KEY_COURSE_OFFERING); String[] orders = ServerConfigurationService.getStrings(SORT_ORDER_COURSE_OFFERING); return sortCmObject(offerings, keys, orders); } // sortCourseOffering /** * Helper method for sortCmObject * by order from sakai properties if specified or * by default of eid, title * using velocity SortTool * * @param courses * @return */ private Collection sortCourseSets(Collection<CourseSet> courses) { // Get the keys from sakai.properties String[] keys = ServerConfigurationService.getStrings(SORT_KEY_COURSE_SET); String[] orders = ServerConfigurationService.getStrings(SORT_ORDER_COURSE_SET); return sortCmObject(courses, keys, orders); } // sortCourseOffering /** * Helper method for sortCmObject * by order from sakai properties if specified or * by default of eid, title * using velocity SortTool * * @param sections * @return */ private Collection sortSections(Collection<Section> sections) { // Get the keys from sakai.properties String[] keys = ServerConfigurationService.getStrings(SORT_KEY_SECTION); String[] orders = ServerConfigurationService.getStrings(SORT_ORDER_SECTION); return sortCmObject(sections, keys, orders); } // sortCourseOffering /** * Helper method for sortCmObject * by order from sakai properties if specified or * by default of eid, title * using velocity SortTool * * @param sessions * @return */ private Collection sortAcademicSessions(Collection<AcademicSession> sessions) { // Get the keys from sakai.properties String[] keys = ServerConfigurationService.getStrings(SORT_KEY_SESSION); String[] orders = ServerConfigurationService.getStrings(SORT_ORDER_SESSION); return sortCmObject(sessions, keys, orders); } // sortCourseOffering /** * Custom sort CM collections using properties provided object has getter & setter for * properties in keys and orders * defaults to eid & title if none specified * * @param collection a collection to be sorted * @param keys properties to sort on * @param orders properties on how to sort (asc, dsc) * @return Collection the sorted collection */ private Collection sortCmObject(Collection collection, String[] keys, String[] orders) { if (collection != null && !collection.isEmpty()) { // Add them to a list for the SortTool (they must have the form // "<key:order>" in this implementation) List propsList = new ArrayList(); if (keys == null || orders == null || keys.length == 0 || orders.length == 0) { // No keys are specified, so use the default sort order propsList.add("eid"); propsList.add("title"); } else { // Populate propsList for (int i = 0; i < Math.min(keys.length, orders.length); i++) { String key = keys[i]; String order = orders[i]; propsList.add(key + ":" + order); } } // Sort the collection and return SortTool sort = new SortTool(); return sort.sort(collection, propsList); } return Collections.emptyList(); } // sortCmObject /** * Custom sort CM collections provided object has getter & setter for * eid & title * * @param collection a collection to be sorted * @return Collection the sorted collection */ private Collection sortCmObject(Collection collection) { return sortCmObject(collection, null, null); } /** * this object is used for displaying purposes in chef_site-newSiteCourse.vm */ public class SectionObject { public Section section; public String eid; public String title; public String category; public String categoryDescription; public boolean isLecture; public boolean attached; public List<String> authorizer; public String description; public SectionObject(Section section) { this.section = section; this.eid = section.getEid(); this.title = section.getTitle(); this.category = section.getCategory(); List<String> authorizers = new ArrayList<String>(); if (section.getEnrollmentSet() != null) { Set<String> instructorset = section.getEnrollmentSet().getOfficialInstructors(); if (instructorset != null) { for (String instructor : instructorset) { authorizers.add(instructor); } } } this.authorizer = authorizers; this.categoryDescription = cms.getSectionCategoryDescription(section.getCategory()); if ("01.lct".equals(section.getCategory())) { this.isLecture = true; } else { this.isLecture = false; } Set set = authzGroupService.getAuthzGroupIds(section.getEid()); if (set != null && !set.isEmpty()) { this.attached = true; } else { this.attached = false; } this.description = section.getDescription(); } public Section getSection() { return section; } public String getEid() { return eid; } public String getTitle() { return title; } public String getCategory() { return category; } public String getCategoryDescription() { return categoryDescription; } public boolean getIsLecture() { return isLecture; } public boolean getAttached() { return attached; } public String getDescription() { return description; } public List<String> getAuthorizer() { return authorizer; } public String getAuthorizerString() { StringBuffer rv = new StringBuffer(); if (authorizer != null && !authorizer.isEmpty()) { for (int count = 0; count < authorizer.size(); count++) { // concatenate all authorizers into a String if (count > 0) { rv.append(", "); } rv.append(authorizer.get(count)); } } return rv.toString(); } public void setAuthorizer(List<String> authorizer) { this.authorizer = authorizer; } } // SectionObject constructor /** * this object is used for displaying purposes in chef_site-newSiteCourse.vm */ public class CourseObject { public String eid; public String title; public List courseOfferingObjects; public CourseObject(CourseOffering offering, List courseOfferingObjects) { this.eid = offering.getEid(); this.title = offering.getTitle(); this.courseOfferingObjects = courseOfferingObjects; } public String getEid() { return eid; } public String getTitle() { return title; } public List getCourseOfferingObjects() { return courseOfferingObjects; } } // CourseObject constructor /** * this object is used for displaying purposes in chef_site-newSiteCourse.vm */ public class CourseOfferingObject { public String eid; public String title; public List sections; public CourseOfferingObject(CourseOffering offering, List unsortedSections) { List propsList = new ArrayList(); propsList.add("category"); propsList.add("eid"); SortTool sort = new SortTool(); this.sections = new ArrayList(); if (unsortedSections != null) { this.sections = (List) sort.sort(unsortedSections, propsList); } this.eid = offering.getEid(); this.title = offering.getTitle(); } public String getEid() { return eid; } public String getTitle() { return title; } public List getSections() { return sections; } } // CourseOfferingObject constructor /** * get campus user directory for dispaly in chef_newSiteCourse.vm * * @return */ private String getCampusDirectory() { return ServerConfigurationService.getString("site-manage.campusUserDirectory", null); } // getCampusDirectory private void removeAnyFlagedSection(SessionState state, ParameterParser params) { List all = new ArrayList(); List providerCourseList = (List) state.getAttribute(STATE_ADD_CLASS_PROVIDER_CHOSEN); if (providerCourseList != null && providerCourseList.size() > 0) { all.addAll(providerCourseList); } List manualCourseList = (List) state.getAttribute(SITE_MANUAL_COURSE_LIST); if (manualCourseList != null && manualCourseList.size() > 0) { all.addAll(manualCourseList); } for (int i = 0; i < all.size(); i++) { String eid = (String) all.get(i); String field = "removeSection" + eid; String toRemove = params.getString(field); if ("true".equals(toRemove)) { // eid is in either providerCourseList or manualCourseList // either way, just remove it if (providerCourseList != null) providerCourseList.remove(eid); if (manualCourseList != null) manualCourseList.remove(eid); } } // if list is empty, set to null. This is important 'cos null is // the indication that the list is empty in the code. See case 2 on line // 1081 if (manualCourseList != null && manualCourseList.size() == 0) manualCourseList = null; if (providerCourseList != null && providerCourseList.size() == 0) providerCourseList = null; removeAnyFlaggedSectionFromState(state, params, STATE_CM_REQUESTED_SECTIONS); removeAnyFlaggedSectionFromState(state, params, STATE_CM_SELECTED_SECTIONS); removeAnyFlaggedSectionFromState(state, params, STATE_CM_AUTHORIZER_SECTIONS); // remove manually requested sections if (state.getAttribute(STATE_MANUAL_ADD_COURSE_NUMBER) != null) { int number = ((Integer) state.getAttribute(STATE_MANUAL_ADD_COURSE_NUMBER)).intValue(); List requiredFields = state.getAttribute(STATE_MANUAL_ADD_COURSE_FIELDS) != null ? (List) state.getAttribute(STATE_MANUAL_ADD_COURSE_FIELDS) : new Vector(); List removeRequiredFieldList = null; for (int i = 0; i < requiredFields.size(); i++) { String sectionTitle = ""; List requiredFieldList = (List) requiredFields.get(i); for (int j = 0; j < requiredFieldList.size(); j++) { SectionField requiredField = (SectionField) requiredFieldList.get(j); sectionTitle = sectionTitle.concat(requiredField.getValue() + " "); } String field = "removeSection" + sectionTitle.trim(); String toRemove = params.getString(field); if ("true".equals(toRemove)) { removeRequiredFieldList = requiredFieldList; break; } } if (removeRequiredFieldList != null) { requiredFields.remove(removeRequiredFieldList); if (number > 1) { state.setAttribute(STATE_MANUAL_ADD_COURSE_FIELDS, requiredFields); state.setAttribute(STATE_MANUAL_ADD_COURSE_NUMBER, Integer.valueOf(number - 1)); } else { state.removeAttribute(STATE_MANUAL_ADD_COURSE_FIELDS); state.removeAttribute(STATE_MANUAL_ADD_COURSE_NUMBER); } } } } private void removeAnyFlaggedSectionFromState(SessionState state, ParameterParser params, String state_variable) { List<SectionObject> rv = (List<SectionObject>) state.getAttribute(state_variable); if (rv != null) { for (int i = 0; i < rv.size(); i++) { SectionObject so = (SectionObject) rv.get(i); String field = "removeSection" + so.getEid(); String toRemove = params.getString(field); if ("true".equals(toRemove)) { rv.remove(so); } } if (rv.size() == 0) state.removeAttribute(state_variable); else state.setAttribute(state_variable, rv); } } private void collectNewSiteInfo(SessionState state, ParameterParser params, List providerChosenList) { if (state.getAttribute(STATE_MESSAGE) == null) { SiteInfo siteInfo = state.getAttribute(STATE_SITE_INFO) != null ? (SiteInfo) state.getAttribute(STATE_SITE_INFO) : new SiteInfo(); // site title is the title of the 1st section selected - // daisyf's note if (providerChosenList != null && providerChosenList.size() >= 1) { String title = prepareTitle((List) state.getAttribute(STATE_PROVIDER_SECTION_LIST), providerChosenList); siteInfo.title = title; } if (state.getAttribute(STATE_ADD_CLASS_PROVIDER_DESCRIPTION_CHOSEN) != null) { List<String> providerDescriptionChosenList = (List<String>) state .getAttribute(STATE_ADD_CLASS_PROVIDER_DESCRIPTION_CHOSEN); if (providerDescriptionChosenList != null) { for (String providerSectionId : providerDescriptionChosenList) { try { Section s = cms.getSection(providerSectionId); if (s != null) { String sDescription = StringUtils.trimToNull(s.getDescription()); if (sDescription != null && !siteInfo.description.contains(sDescription)) { siteInfo.description = siteInfo.description.concat(sDescription); } } } catch (IdNotFoundException e) { M_log.warn("collectNewSiteInfo: cannot find section " + providerSectionId); } } } } state.setAttribute(STATE_SITE_INFO, siteInfo); if (params.getString("manualAdds") != null && ("true").equals(params.getString("manualAdds"))) { // if creating a new site state.setAttribute(STATE_TEMPLATE_INDEX, "37"); state.setAttribute(STATE_MANUAL_ADD_COURSE_NUMBER, Integer.valueOf(1)); } else if (params.getString("find_course") != null && ("true").equals(params.getString("find_course"))) { state.setAttribute(STATE_ADD_CLASS_PROVIDER_CHOSEN, providerChosenList); prepFindPage(state); } else { // no manual add state.removeAttribute(STATE_MANUAL_ADD_COURSE_NUMBER); state.removeAttribute(STATE_MANUAL_ADD_COURSE_FIELDS); state.removeAttribute(STATE_SITE_QUEST_UNIQNAME); if (getStateSite(state) != null) { // if revising a site, go to the confirmation // page of adding classes //state.setAttribute(STATE_TEMPLATE_INDEX, "37"); } else { // if creating a site, go the the site // information entry page state.setAttribute(STATE_TEMPLATE_INDEX, "13"); } } } } /** * By default, courseManagement is implemented * * @return */ private boolean courseManagementIsImplemented() { boolean returnValue = true; String isImplemented = ServerConfigurationService.getString("site-manage.courseManagementSystemImplemented", "true"); if (("false").equals(isImplemented)) returnValue = false; return returnValue; } private List getCMSections(String offeringEid) { if (offeringEid == null || offeringEid.trim().length() == 0) return null; if (cms != null) { try { Set sections = cms.getSections(offeringEid); if (sections != null) { Collection c = sortSections(new ArrayList(sections)); return (List) c; } } catch (IdNotFoundException e) { M_log.warn("getCMSections: Cannot find sections for " + offeringEid); } } return new ArrayList(0); } private List getCMCourseOfferings(String subjectEid, String termID) { if (subjectEid == null || subjectEid.trim().length() == 0 || termID == null || termID.trim().length() == 0) return null; if (cms != null) { Set offerings = cms.getCourseOfferingsInCourseSet(subjectEid);// , // termID); ArrayList returnList = new ArrayList(); if (offerings != null) { Iterator coIt = offerings.iterator(); while (coIt.hasNext()) { CourseOffering co = (CourseOffering) coIt.next(); AcademicSession as = co.getAcademicSession(); if (as != null && as.getEid().equals(termID)) returnList.add(co); } } Collection c = sortCourseOfferings(returnList); return (List) c; } return new ArrayList(0); } private List<String> getCMLevelLabels(SessionState state) { List<String> rv = new Vector<String>(); // get CourseSet Set courseSets = getCourseSet(state); String currentLevel = ""; if (courseSets != null) { // Hieriarchy of CourseSet, CourseOffering and Section are multiple levels in CourseManagementService List<SectionField> sectionFields = sectionFieldProvider.getRequiredFields(); for (SectionField field : sectionFields) { rv.add(field.getLabelKey()); } } return rv; } /** * a recursive function to add courseset categories * @param rv * @param courseSets */ private List<String> addCategories(List<String> rv, Set courseSets) { if (courseSets != null) { for (Iterator i = courseSets.iterator(); i.hasNext();) { // get the CourseSet object level CourseSet cs = (CourseSet) i.next(); String level = cs.getCategory(); if (!rv.contains(level)) { rv.add(level); } try { // recursively add child categories rv = addCategories(rv, cms.getChildCourseSets(cs.getEid())); } catch (IdNotFoundException e) { // current CourseSet not found } } } return rv; } private void prepFindPage(SessionState state) { // check the configuration setting for choosing next screen Boolean skipCourseSectionSelection = ServerConfigurationService .getBoolean(SAK_PROP_SKIP_COURSE_SECTION_SELECTION, Boolean.FALSE); if (!skipCourseSectionSelection.booleanValue()) { // go to the course/section selection page state.setAttribute(STATE_TEMPLATE_INDEX, "53"); // get cm levels final List cmLevels = getCMLevelLabels(state), selections = (List) state.getAttribute(STATE_CM_LEVEL_SELECTIONS); int lvlSz = 0; if (cmLevels == null || (lvlSz = cmLevels.size()) < 1) { // TODO: no cm levels configured, redirect to manual add return; } if (selections != null && selections.size() >= lvlSz) { // multiple selections for the section level List<SectionObject> soList = new Vector<SectionObject>(); for (int k = cmLevels.size() - 1; k < selections.size(); k++) { String string = (String) selections.get(k); if (string != null && string.length() > 0) { try { Section sect = cms.getSection(string); if (sect != null) { SectionObject so = new SectionObject(sect); soList.add(so); } } catch (IdNotFoundException e) { M_log.warn("prepFindPage: Cannot find section " + string); } } } state.setAttribute(STATE_CM_SELECTED_SECTION, soList); } else state.removeAttribute(STATE_CM_SELECTED_SECTION); state.setAttribute(STATE_CM_LEVELS, cmLevels); state.setAttribute(STATE_CM_LEVEL_SELECTIONS, selections); } else { // skip the course/section selection page, go directly into the manually create course page state.setAttribute(STATE_TEMPLATE_INDEX, "37"); } } private void addRequestedSection(SessionState state) { List<SectionObject> soList = (List<SectionObject>) state.getAttribute(STATE_CM_SELECTED_SECTION); String uniqueName = (String) state.getAttribute(STATE_SITE_QUEST_UNIQNAME); if (soList == null || soList.isEmpty()) return; String s = ServerConfigurationService.getString("officialAccountName"); if (uniqueName == null) { addAlert(state, rb.getFormattedMessage("java.author", new Object[] { ServerConfigurationService.getString("officialAccountName") })); return; } if (getStateSite(state) == null) { // creating new site List<SectionObject> requestedSections = (List<SectionObject>) state .getAttribute(STATE_CM_REQUESTED_SECTIONS); for (SectionObject so : soList) { so.setAuthorizer(new ArrayList(Arrays.asList(uniqueName.split(",")))); if (requestedSections == null) { requestedSections = new ArrayList<SectionObject>(); } // don't add duplicates if (!requestedSections.contains(so)) requestedSections.add(so); } state.setAttribute(STATE_CM_REQUESTED_SECTIONS, requestedSections); state.removeAttribute(STATE_CM_SELECTED_SECTION); // if the title has not yet been set and there is just // one section, set the title to that section's EID SiteInfo siteInfo = (SiteInfo) state.getAttribute(STATE_SITE_INFO); if (siteInfo == null) { siteInfo = new SiteInfo(); } if (siteInfo.title == null || siteInfo.title.trim().length() == 0) { if (requestedSections.size() >= 1) { siteInfo.title = requestedSections.get(0).getTitle(); state.setAttribute(STATE_SITE_INFO, siteInfo); } } } else { // editing site for (SectionObject so : soList) { so.setAuthorizer(new ArrayList(Arrays.asList(uniqueName.split(",")))); List<SectionObject> cmSelectedSections = (List<SectionObject>) state .getAttribute(STATE_CM_SELECTED_SECTIONS); if (cmSelectedSections == null) { cmSelectedSections = new ArrayList<SectionObject>(); } // don't add duplicates if (!cmSelectedSections.contains(so)) cmSelectedSections.add(so); state.setAttribute(STATE_CM_SELECTED_SECTIONS, cmSelectedSections); state.removeAttribute(STATE_CM_SELECTED_SECTION); } } state.removeAttribute(STATE_CM_LEVEL_SELECTIONS); } public void doFind_course(RunData data) { final SessionState state = ((JetspeedRunData) data) .getPortletSessionState(((JetspeedRunData) data).getJs_peid()); final ParameterParser params = data.getParameters(); final String option = params.get("option"); if (option != null && option.length() > 0) { if ("continue".equals(option)) { String uniqname = StringUtils.trimToNull(params.getString("uniqname")); state.setAttribute(STATE_SITE_QUEST_UNIQNAME, uniqname); if (state.getAttribute(STATE_FUTURE_TERM_SELECTED) != null && !((Boolean) state.getAttribute(STATE_FUTURE_TERM_SELECTED)).booleanValue()) { // if a future term is selected, do not check authorization // uniqname if (uniqname == null) { addAlert(state, rb.getFormattedMessage("java.author", new Object[] { ServerConfigurationService.getString("officialAccountName") })); } else { // check instructors List instructors = new ArrayList(Arrays.asList(uniqname.split(","))); for (Iterator iInstructors = instructors.iterator(); iInstructors.hasNext();) { String instructorId = (String) iInstructors.next(); try { UserDirectoryService.getUserByEid(instructorId); } catch (UserNotDefinedException e) { addAlert(state, rb.getFormattedMessage("java.validAuthor", new Object[] { ServerConfigurationService.getString("officialAccountName") })); M_log.warn(this + ".doFind_course:" + rb.getFormattedMessage("java.validAuthor", new Object[] { ServerConfigurationService.getString("officialAccountName") })); } } if (state.getAttribute(STATE_MESSAGE) == null) { addRequestedSection(state); } } } else { addRequestedSection(state); } if (state.getAttribute(STATE_MESSAGE) == null) { // no manual add state.removeAttribute(STATE_MANUAL_ADD_COURSE_NUMBER); state.removeAttribute(STATE_MANUAL_ADD_COURSE_FIELDS); if (getStateSite(state) == null) { if (state.getAttribute(STATE_TEMPLATE_SITE) != null) { // if creating site using template, stop here and generate the new site // create site based on template doFinish(data); } else { // else follow the normal flow state.setAttribute(STATE_TEMPLATE_INDEX, "13"); } } else { state.setAttribute(STATE_TEMPLATE_INDEX, "44"); } } doContinue(data); return; } else if ("back".equals(option)) { doBack(data); return; } else if ("cancel".equals(option)) { if (getStateSite(state) == null) { doCancel_create(data);// cancel from new site creation } else { doCancel(data);// cancel from site info editing } return; } else if ("add".equals(option)) { // get the uniqname input String uniqname = StringUtils.trimToNull(params.getString("uniqname")); state.setAttribute(STATE_SITE_QUEST_UNIQNAME, uniqname); addRequestedSection(state); return; } else if ("manual".equals(option)) { // TODO: send to case 37 state.setAttribute(STATE_TEMPLATE_INDEX, "37"); state.setAttribute(STATE_MANUAL_ADD_COURSE_NUMBER, Integer.valueOf(1)); return; } else if ("remove".equals(option)) removeAnyFlagedSection(state, params); } final List selections = new ArrayList(3); int cmLevel = getCMLevelLabels(state).size(); String cmLevelChanged = params.get("cmLevelChanged"); if ("true".equals(cmLevelChanged)) { // when cm level changes, set the focus to the new level String cmChangedLevel = params.get("cmChangedLevel"); cmLevel = cmChangedLevel != null ? Integer.valueOf(cmChangedLevel).intValue() + 1 : cmLevel; } for (int i = 0; i < cmLevel; i++) { String[] val = params.getStrings("idField_" + i); if (val == null || val.length == 0) { break; } if (val.length == 1) { selections.add(val[0]); } else { for (int k = 0; k < val.length; k++) { selections.add(val[k]); } } } state.setAttribute(STATE_CM_LEVEL_SELECTIONS, selections); prepFindPage(state); } /** * return the title of the 1st section in the chosen list that has an * enrollment set. No discrimination on section category * * @param sectionList * @param chosenList * @return */ private String prepareTitle(List sectionList, List chosenList) { String title = null; HashMap map = new HashMap(); for (Iterator i = sectionList.iterator(); i.hasNext();) { SectionObject o = (SectionObject) i.next(); map.put(o.getEid(), o.getSection()); } for (int j = 0; j < chosenList.size(); j++) { String eid = (String) chosenList.get(j); Section s = (Section) map.get(eid); // we will always has a title regardless but we prefer it to be the // 1st section on the chosen list that has an enrollment set if (j == 0) { title = s.getTitle(); } if (s.getEnrollmentSet() != null) { title = s.getTitle(); break; } } return title; } // prepareTitle /** * return an ArrayList of SectionObject * * @param sectionHash * contains an ArrayList collection of SectionObject * @return */ private ArrayList getSectionList(HashMap sectionHash) { ArrayList list = new ArrayList(); // values is an ArrayList of section Collection c = sectionHash.values(); for (Iterator i = c.iterator(); i.hasNext();) { ArrayList l = (ArrayList) i.next(); list.addAll(l); } return list; } private String getAuthorizers(SessionState state, String attributeName) { String authorizers = ""; ArrayList list = (ArrayList) state.getAttribute(attributeName); if (list != null) { for (int i = 0; i < list.size(); i++) { if (i == 0) { authorizers = (String) list.get(i); } else { authorizers = authorizers + ", " + list.get(i); } } } return authorizers; } private List prepareSectionObject(List sectionList, String userId) { ArrayList list = new ArrayList(); if (sectionList != null) { for (int i = 0; i < sectionList.size(); i++) { String sectionEid = (String) sectionList.get(i); try { Section s = cms.getSection(sectionEid); if (s != null) { SectionObject so = new SectionObject(s); so.setAuthorizer(new ArrayList(Arrays.asList(userId.split(",")))); list.add(so); } } catch (IdNotFoundException e) { M_log.warn("prepareSectionObject: Cannot find section " + sectionEid); } } } return list; } /** * change collection object to list object * @param c * @return */ private List collectionToList(Collection c) { List rv = new Vector(); if (c != null) { for (Iterator i = c.iterator(); i.hasNext();) { rv.add(i.next()); } } return rv; } protected void toolModeDispatch(String methodBase, String methodExt, HttpServletRequest req, HttpServletResponse res) throws ToolException { ToolSession toolSession = SessionManager.getCurrentToolSession(); SessionState state = getState(req); if (SITE_MODE_HELPER_DONE.equals(state.getAttribute(STATE_SITE_MODE))) { String url = (String) SessionManager.getCurrentToolSession().getAttribute(Tool.HELPER_DONE_URL); SessionManager.getCurrentToolSession().removeAttribute(Tool.HELPER_DONE_URL); // TODO: Implement cleanup. cleanState(state); // Helper cleanup. cleanStateHelper(state); if (M_log.isDebugEnabled()) { M_log.debug("Sending redirect to: " + url); } try { res.sendRedirect(url); } catch (IOException e) { M_log.error("Problem sending redirect to: " + url, e); } return; } else { super.toolModeDispatch(methodBase, methodExt, req, res); } } private void cleanStateHelper(SessionState state) { state.removeAttribute(STATE_SITE_MODE); state.removeAttribute(STATE_TEMPLATE_INDEX); state.removeAttribute(STATE_INITIALIZED); } private String getSiteBaseUrl() { return ServerConfigurationService.getPortalUrl() + "/" + ServerConfigurationService.getString("portal.handler.default", "site") + "/"; } private String getDefaultSiteUrl(String siteId) { return prefixString(getSiteBaseUrl(), siteId); } private Collection<String> getSiteReferenceAliasIds(Site forSite) { return prefixSiteAliasIds(null, forSite); } private Collection<String> getSiteUrlsForSite(Site site) { return prefixSiteAliasIds(getSiteBaseUrl(), site); } private Collection<String> getSiteUrlsForAliasIds(Collection<String> aliasIds) { return prefixSiteAliasIds(getSiteBaseUrl(), aliasIds); } private String getSiteUrlForAliasId(String aliasId) { return prefixString(getSiteBaseUrl(), aliasId); } private Collection<String> prefixSiteAliasIds(String prefix, Site site) { return prefixSiteAliasIds(prefix, aliasService.getAliases(site.getReference())); } private Collection<String> prefixSiteAliasIds(String prefix, Collection<? extends Object> aliases) { List<String> siteAliases = new ArrayList<String>(); for (Object alias : aliases) { String aliasId = null; if (alias instanceof Alias) { aliasId = ((Alias) alias).getId(); } else { aliasId = alias.toString(); } siteAliases.add(prefixString(prefix, aliasId)); } return siteAliases; } private String prefixString(String prefix, String aliasId) { return (prefix == null ? "" : prefix) + aliasId; } private List<String> toIdList(List<? extends Entity> entities) { List<String> ids = new ArrayList<String>(entities.size()); for (Entity entity : entities) { ids.add(entity.getId()); } return ids; } /** * whether this tool title is of Home tool title * @param toolTitle * @return */ private boolean isHomePage(SitePage page) { if (page.getProperties().getProperty(SitePage.IS_HOME_PAGE) != null) { // check based on the page property first return true; } else { // if above fails, check based on the page title String pageTitle = page.getTitle(); return TOOL_ID_HOME.equalsIgnoreCase(pageTitle) || rb.getString("java.home").equalsIgnoreCase(pageTitle); } } public boolean displaySiteAlias() { if (ServerConfigurationService.getBoolean("wsetup.disable.siteAlias", false)) { return false; } return true; } private void putPrintParticipantLinkIntoContext(Context context, RunData data, Site site) { // the status servlet reqest url String url = Web.serverUrl(data.getRequest()) + "/sakai-site-manage-tool/tool/printparticipant/" + site.getId(); context.put("printParticipantUrl", url); } /** * dispatch function for site type vm * @param data */ public void doSite_type_option(RunData data) { ParameterParser params = data.getParameters(); String option = StringUtils.trimToNull(params.getString("option")); SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); if (option != null) { if ("cancel".equals(option)) { doCancel_create(data); } else if ("siteType".equals(option)) { doSite_type(data); } else if ("createOnTemplate".equals(option)) { doSite_copyFromTemplate(data); } else if ("createCourseOnTemplate".equals(option)) { doSite_copyFromCourseTemplate(data); } else if ("createCourseOnTemplate".equals(option)) { doSite_copyFromCourseTemplate(data); } else if ("createFromArchive".equals(option)) { state.setAttribute(STATE_CREATE_FROM_ARCHIVE, Boolean.TRUE); //continue with normal workflow doSite_type(data); } } } /** * create site from template * @param params * @param state */ private void doSite_copyFromTemplate(RunData data) { ParameterParser params = data.getParameters(); SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); // read template information readCreateSiteTemplateInformation(params, state); // create site doFinish(data); } /** * create course site from template, next step would be select roster * @param params * @param state */ private void doSite_copyFromCourseTemplate(RunData data) { ParameterParser params = data.getParameters(); SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); // read template information readCreateSiteTemplateInformation(params, state); // redirect for site roster selection redirectCourseCreation(params, state, "selectTermTemplate"); } /** * read the user input for creating site based on template * @param params * @param state */ private void readCreateSiteTemplateInformation(ParameterParser params, SessionState state) { // get the template site id String templateSiteId = params.getString("templateSiteId"); try { Site templateSite = SiteService.getSite(templateSiteId); state.setAttribute(STATE_TEMPLATE_SITE, templateSite); state.setAttribute(STATE_SITE_TYPE, templateSite.getType()); SiteInfo siteInfo = new SiteInfo(); if (state.getAttribute(STATE_SITE_INFO) != null) { siteInfo = (SiteInfo) state.getAttribute(STATE_SITE_INFO); } siteInfo.site_type = templateSite.getType(); siteInfo.title = StringUtils.trimToNull(params.getString("siteTitleField")); siteInfo.term = StringUtils.trimToNull(params.getString("selectTermTemplate")); siteInfo.iconUrl = templateSite.getIconUrl(); Boolean copyTemplateDescription = ServerConfigurationService .getBoolean(SAK_PROP_COPY_TEMPLATE_DESCRIPTION, Boolean.TRUE); if (copyTemplateDescription.booleanValue()) { siteInfo.description = templateSite.getDescription(); } siteInfo.short_description = templateSite.getShortDescription(); siteInfo.joinable = templateSite.isJoinable(); siteInfo.joinerRole = templateSite.getJoinerRole(); state.setAttribute(STATE_SITE_INFO, siteInfo); // bjones86 - SAK-24423 - update site info for joinable site settings JoinableSiteSettings.updateSiteInfoFromParams(params, siteInfo); // whether to copy users or site content over? if (params.getBoolean("copyUsers")) state.setAttribute(STATE_TEMPLATE_SITE_COPY_USERS, Boolean.TRUE); else state.removeAttribute(STATE_TEMPLATE_SITE_COPY_USERS); if (params.getBoolean("copyContent")) state.setAttribute(STATE_TEMPLATE_SITE_COPY_CONTENT, Boolean.TRUE); else state.removeAttribute(STATE_TEMPLATE_SITE_COPY_CONTENT); if (params.getBoolean("publishSite")) state.setAttribute(STATE_TEMPLATE_PUBLISH, Boolean.TRUE); else state.removeAttribute(STATE_TEMPLATE_PUBLISH); } catch (Exception e) { M_log.warn(this + "readCreateSiteTemplateInformation: problem of getting template site: " + templateSiteId); } } /** * redirect course creation process after the term selection step * @param params * @param state * @param termFieldName */ private void redirectCourseCreation(ParameterParser params, SessionState state, String termFieldName) { User user = UserDirectoryService.getCurrentUser(); String currentUserId = user.getEid(); String userId = params.getString("userId"); if (userId == null || "".equals(userId)) { userId = currentUserId; } else { // implies we are trying to pick sections owned by other // users. Currently "select section by user" page only // take one user per sitte request - daisy's note 1 ArrayList<String> list = new ArrayList(); list.add(userId); state.setAttribute(STATE_CM_AUTHORIZER_LIST, list); } state.setAttribute(STATE_INSTRUCTOR_SELECTED, userId); String academicSessionEid = params.getString(termFieldName); // check whether the academicsession might be null if (academicSessionEid != null) { AcademicSession t = cms.getAcademicSession(academicSessionEid); state.setAttribute(STATE_TERM_SELECTED, t); if (t != null) { List sections = prepareCourseAndSectionListing(userId, t.getEid(), state); isFutureTermSelected(state); if (sections != null && sections.size() > 0) { state.setAttribute(STATE_TERM_COURSE_LIST, sections); state.setAttribute(STATE_TEMPLATE_INDEX, "36"); state.setAttribute(STATE_AUTO_ADD, Boolean.TRUE); } else { state.removeAttribute(STATE_TERM_COURSE_LIST); Boolean skipCourseSectionSelection = ServerConfigurationService .getBoolean(SAK_PROP_SKIP_COURSE_SECTION_SELECTION, Boolean.FALSE); if (!skipCourseSectionSelection.booleanValue() && courseManagementIsImplemented()) { state.setAttribute(STATE_TEMPLATE_INDEX, "53"); } else { state.setAttribute(STATE_TEMPLATE_INDEX, "37"); } } } else { // not course type state.setAttribute(STATE_TEMPLATE_INDEX, "37"); } } } public void doEdit_site_info(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); ParameterParser params = data.getParameters(); String locale_string = params.getString("locales"); state.setAttribute("locale_string", locale_string); String option = params.getString("option"); if ("removeSection".equals(option)) { // remove section removeAnyFlagedSection(state, params); } else if ("continue".equals(option)) { // continue with site information edit MathJaxEnabler.applyAllowedSettingsToState(state, params); // SAK-22384 doContinue(data); } else if ("back".equals(option)) { // go back to previous pages doBack(data); } else if ("cancel".equals(option)) { // cancel doCancel(data); } } /** * * * * @return Locale based on its string representation (language_region) */ private Locale getLocaleFromString(String localeString) { org.sakaiproject.component.api.ServerConfigurationService scs = (org.sakaiproject.component.api.ServerConfigurationService) ComponentManager .get(org.sakaiproject.component.api.ServerConfigurationService.class); return scs.getLocaleFromString(localeString); } /** * Handle the eventSubmit_doUnjoin command to have the user un-join this site. */ public void doUnjoin(RunData data) { SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); final ParameterParser params = data.getParameters(); final String id = params.get("itemReference"); String siteTitle = null; if (id != null) { try { siteTitle = SiteService.getSite(id).getTitle(); SiteService.unjoin(id); String msg = rb.getString("sitinfimp.youhave") + " " + siteTitle; addAlert(state, msg); } catch (IdUnusedException ignore) { } catch (PermissionException e) { // This could occur if the user's role is the maintain role for the site, and we don't let the user // unjoin sites they are maintainers of Log.warn("chef", this + ".doUnjoin(): " + e); //TODO can't access site so redirect to portal } catch (InUseException e) { addAlert(state, siteTitle + " " + rb.getString("sitinfimp.sitebeing") + " "); } } // refresh the whole page scheduleTopRefresh(); } // doUnjoin /** * @return Returns the prefLocales */ public List<Locale> getPrefLocales() { // Initialize list of supported locales, if necessary if (prefLocales.size() == 0) { org.sakaiproject.component.api.ServerConfigurationService scs = (org.sakaiproject.component.api.ServerConfigurationService) ComponentManager .get(org.sakaiproject.component.api.ServerConfigurationService.class); Locale[] localeArray = scs.getSakaiLocales(); // Add to prefLocales list for (int i = 0; i < localeArray.length; i++) { prefLocales.add(localeArray[i]); } } return prefLocales; } // SAK-20797 /** * return quota on site specified by siteId * @param siteId * @return value of site-specific quota or 0 if not found */ private long getSiteSpecificQuota(String siteId) { long quota = 0; try { Site site = SiteService.getSite(siteId); if (site != null) { quota = getSiteSpecificQuota(site); } } catch (IdUnusedException e) { M_log.error( "Quota calculation could not find the site " + siteId + "for site specific quota calculation", M_log.isDebugEnabled() ? e : null); } return quota; } // SAK-20797 /** * return quota set on this specific site * @param collection * @return value of site-specific quota or 0 if not found */ private long getSiteSpecificQuota(Site site) { long quota = 0; try { String collId = m_contentHostingService.getSiteCollection(site.getId()); ContentCollection site_collection = m_contentHostingService.getCollection(collId); long siteSpecific = site_collection.getProperties() .getLongProperty(ResourceProperties.PROP_COLLECTION_BODY_QUOTA); quota = siteSpecific; } catch (Exception ignore) { M_log.warn("getQuota: reading quota property for site : " + site.getId() + " : " + ignore); quota = 0; } return quota; } // SAK-20797 /** * return file size in bytes as formatted string * @param quota * @return formatted string (i.e. 2048 as 2 KB) */ private String formatSize(long quota) { String size = ""; NumberFormat formatter = NumberFormat.getInstance(rb.getLocale()); formatter.setMaximumFractionDigits(1); if (quota > 700000000L) { String[] args = { formatter.format(1.0 * quota / (1024L * 1024L * 1024L)) }; size = rb.getFormattedMessage("size.gb", args); } else if (quota > 700000L) { String[] args = { formatter.format(1.0 * quota / (1024L * 1024L)) }; size = rb.getFormattedMessage("size.mb", args); } else if (quota > 700L) { String[] args = { formatter.format(1.0 * quota / 1024L) }; size = rb.getFormattedMessage("size.kb", args); } else { String[] args = { formatter.format(quota) }; size = rb.getFormattedMessage("size.bytes", args); } return size; } public class JoinableGroup { private String reference; private String title; private String joinableSet; private int size; private int max; private String members; private boolean preview; public JoinableGroup(String reference, String title, String joinableSet, int size, int max, String members, boolean preview) { this.reference = reference; this.title = title; this.joinableSet = joinableSet; this.size = size; this.max = max; this.members = members; this.preview = preview; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getJoinableSet() { return joinableSet; } public void setJoinableSet(String joinableSet) { this.joinableSet = joinableSet; } public int getSize() { return size; } public void setSize(int size) { this.size = size; } public int getMax() { return max; } public void setMax(int max) { this.max = max; } public String getMembers() { return members; } public void setMembers(String members) { this.members = members; } public boolean isPreview() { return preview; } public void setPreview(boolean preview) { this.preview = preview; } public String getReference() { return reference; } public void setReference(String reference) { this.reference = reference; } } /** * Handles uploading an archive file as part of the site creation workflow * @param data */ public void doUploadArchive(RunData data) { ParameterParser params = data.getParameters(); SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid()); //get params FileItem fi = data.getParameters().getFileItem("importFile"); //get uploaded file into a location we can process String archiveUnzipBase = ServerConfigurationService.getString("archive.storage.path", FileUtils.getTempDirectoryPath()); //convert inputstream into actual file so we can unzip it String zipFilePath = archiveUnzipBase + File.separator + fi.getFileName(); //rudimentary check that the file is a zip file if (!StringUtils.endsWith(fi.getFileName(), ".zip")) { addAlert(state, rb.getString("archive.createsite.failedupload")); return; } File tempZipFile = new File(zipFilePath); if (tempZipFile.exists()) { tempZipFile.delete(); } FileOutputStream fileOutputStream = null; try { fileOutputStream = new FileOutputStream(tempZipFile); //copy contents into this file IOUtils.copyLarge(fi.getInputStream(), fileOutputStream); //set path into state so we can process it later state.setAttribute(STATE_UPLOADED_ARCHIVE_PATH, tempZipFile.getAbsolutePath()); state.setAttribute(STATE_UPLOADED_ARCHIVE_NAME, tempZipFile.getName()); } catch (Exception e) { M_log.error(e.getMessage(), e); //general catch all for the various exceptions that occur above. all are failures. addAlert(state, rb.getString("archive.createsite.failedupload")); } finally { IOUtils.closeQuietly(fileOutputStream); } //go to confirm screen state.setAttribute(STATE_TEMPLATE_INDEX, "10"); } /** * Handles merging an uploaded archive into the newly created site * This is done after the site has been created in the site creation workflow * * @param siteId * @param state */ private void doMergeArchiveIntoNewSite(String siteId, SessionState state) { String currentUserId = userDirectoryService.getCurrentUser().getId(); try { String archivePath = (String) state.getAttribute(STATE_UPLOADED_ARCHIVE_PATH); //merge the zip into our new site //we ignore the return because its not very useful. See ArchiveService for more details archiveService.mergeFromZip(archivePath, siteId, currentUserId); } catch (Exception e) { M_log.error(e.getMessage(), e); //general catch all for the various exceptions that occur above. all are failures. addAlert(state, rb.getString("archive.createsite.failedmerge")); } } /** * Helper to hard delete all implementing services * @param siteId siteId that we want to delete the content for * @return */ private void doHardDelete(String siteId) { // leverage the entityproducer registration system for (Iterator i = EntityManager.getEntityProducers().iterator(); i.hasNext();) { EntityProducer ep = (EntityProducer) i.next(); //if a registered service implements hard delete, then ask it to delete itself if (ep instanceof HardDeleteAware) { HardDeleteAware hd = (HardDeleteAware) ep; M_log.info("Requesting hard delete for site:" + siteId + ", tool: " + ep.getLabel()); hd.hardDelete(siteId); } } } /** * Check if we are adding missing tools when importing * @return */ private boolean isAddMissingToolsOnImportEnabled() { return ServerConfigurationService.getBoolean("site.setup.import.addmissingtools", false); } /** * Helper to add a tool to a site if the site does not contain an instance of the tool * * Note that it does NOT save the site. The caller must handle this. * * @param site the site to check * @param toolId the tool to add (eg sakai.resources) * * @return site the updated site object */ private Site addToolToSiteIfMissing(Site site, String toolId) { if (site.getToolForCommonId(toolId) != null) { return site; } M_log.debug("Adding tool to site: " + site.getId() + ", tool: " + toolId); SitePage page = site.addPage(); //inherit the tool's title. ToolConfiguration tool = page.addTool(); tool.setTool(toolId, ToolManager.getTool(toolId)); tool.setTitle(ToolManager.getTool(toolId).getTitle()); return site; } /** * Get the list of tools that are in a list of sites that are available for import. * * Only tools with content will be collected. See hasContent(toolId, siteId) for the behaviour. * * @param list of siteids to check, could be a singleton * @return a list of toolIds that are in the sites that are available for import * */ private List<String> getToolsInSitesAvailableForImport(List<Site> sites) { List<String> allImportToolIds = new ArrayList<String>(importTools()); List<String> importToolsInSites = new ArrayList<String>(); for (Site site : sites) { for (String toolId : allImportToolIds) { if (site.getToolForCommonId(toolId) != null) { //check the tool has content. //this caters for the case where we only selected one site for import, this means the tool won't show in the list at all. if (hasContent(toolId, site.getId())) { importToolsInSites.add(toolId); } } } } return importToolsInSites; } /** * Get a map of all names for the given list of tools in the given sites. For example if a tool with id sakai.mytool * is called My Tool in one site and An Amazing Tool in another site, the set will contain both for that tool id. * @param toolIds * @param sites * @return */ private Map<String, Set<String>> getToolNames(List<String> toolIds, List<Site> sites) { Map<String, Set<String>> rval = new HashMap<>(); //foreach toolid for (String toolId : toolIds) { //init a set Set<String> toolNames = new HashSet<>(); //for each site for (Site s : sites) { //get the name of this tool in the site for the page it is on, if it exists, add to the list List<ToolConfiguration> toolConfigs = (List<ToolConfiguration>) s.getTools(toolId); for (ToolConfiguration config : toolConfigs) { toolNames.add(config.getContainingPage().getTitle()); } } rval.put(toolId, toolNames); } return rval; } /** * Get a map of tools in each site that have content. * The list of tools are only those that have been selected for import * * The algorithm for determining this is documented as part of hasContent(siteId, toolid); * * @param sites * @param toolIds * @return Map keyed on siteId. Set contains toolIds that have content. */ private Map<String, Set<String>> getSiteImportToolsWithContent(List<Site> sites, List<String> toolIds) { Map<String, Set<String>> siteToolsWithContent = new HashMap<>(); for (Site site : sites) { Set<String> toolsWithContent = new HashSet<>(); for (String toolId : toolIds) { if (site.getToolForCommonId(toolId) != null) { //check the tool has content if (hasContent(toolId, site.getId())) { toolsWithContent.add(toolId); } } } M_log.debug("Site: " + site.getId() + ", has the following tools with content: " + toolsWithContent); siteToolsWithContent.put(site.getId(), toolsWithContent); } return siteToolsWithContent; } /** * Helper to check if a tool in a site has content. * This leverages the EntityProducer system and then checks each producer to see if it is the one we are interested in * If the tool implements the ContentExistsAware interface, then it asks the tool explicitly if it has content. * If the tool does not implement this interface, then we have no way to tell, so for backwards compatibility we assume it has content. * * @param toolId * @param siteId */ private boolean hasContent(String toolId, String siteId) { for (Iterator i = EntityManager.getEntityProducers().iterator(); i.hasNext();) { EntityProducer ep = (EntityProducer) i.next(); if (ep instanceof EntityTransferrer) { EntityTransferrer et = (EntityTransferrer) ep; if (ArrayUtils.contains(et.myToolIds(), toolId)) { if (ep instanceof ContentExistsAware) { ContentExistsAware cea = (ContentExistsAware) ep; M_log.debug("Checking tool content for site:" + siteId + ", tool: " + et.myToolIds()); return cea.hasContent(siteId); } } } } return true; //backwards compatibility } }