0001: /**********************************************************************************
0002: * $URL: https://source.sakaiproject.org/svn/trunk/sakai/admin-tools/su/src/java/org/sakaiproject/tool/su/SuTool.java $
0003: * $Id: SuTool.java 5970 2006-02-15 03:07:19Z ggolden@umich.edu $
0004: ***********************************************************************************
0005: *
0006: * Copyright (c) 203, 2004, 2005, 2006 The Sakai Foundation.
0007: *
0008: * Licensed under the Educational Community License, Version 1.0 (the "License");
0009: * you may not use this file except in compliance with the License.
0010: * You may obtain a copy of the License at
0011: *
0012: * http://www.opensource.org/licenses/ecl1.php
0013: *
0014: * Unless required by applicable law or agreed to in writing, software
0015: * distributed under the License is distributed on an "AS IS" BASIS,
0016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017: * See the License for the specific language governing permissions and
0018: * limitations under the License.
0019: *
0020: **********************************************************************************/package org.sakaiproject.site.impl;
0021:
0022: import java.util.Collection;
0023: import java.util.Iterator;
0024: import java.util.List;
0025: import java.util.Set;
0026: import java.util.Stack;
0027: import java.util.Vector;
0028:
0029: import org.apache.commons.logging.Log;
0030: import org.apache.commons.logging.LogFactory;
0031: import org.sakaiproject.authz.api.AuthzGroup;
0032: import org.sakaiproject.authz.api.GroupNotDefinedException;
0033: import org.sakaiproject.authz.api.Member;
0034: import org.sakaiproject.authz.api.Role;
0035: import org.sakaiproject.authz.api.RoleAlreadyDefinedException;
0036: import org.sakaiproject.authz.cover.AuthzGroupService;
0037: import org.sakaiproject.entity.api.Entity;
0038: import org.sakaiproject.entity.api.Reference;
0039: import org.sakaiproject.entity.api.ResourceProperties;
0040: import org.sakaiproject.entity.api.ResourcePropertiesEdit;
0041: import org.sakaiproject.site.api.Group;
0042: import org.sakaiproject.site.api.Site;
0043: import org.sakaiproject.site.api.SitePage;
0044: import org.sakaiproject.site.api.ToolConfiguration;
0045: import org.sakaiproject.site.cover.SiteService;
0046: import org.sakaiproject.time.api.Time;
0047: import org.sakaiproject.time.cover.TimeService;
0048: import org.sakaiproject.user.api.User;
0049: import org.sakaiproject.user.api.UserNotDefinedException;
0050: import org.sakaiproject.user.cover.UserDirectoryService;
0051: import org.sakaiproject.util.BaseResourceProperties;
0052: import org.sakaiproject.util.BaseResourcePropertiesEdit;
0053: import org.sakaiproject.util.StringUtil;
0054: import org.sakaiproject.util.Xml;
0055: import org.w3c.dom.Document;
0056: import org.w3c.dom.Element;
0057: import org.w3c.dom.Node;
0058: import org.w3c.dom.NodeList;
0059:
0060: /**
0061: * <p>
0062: * BaseSite is a base implementation of the Site API Site.
0063: * </p>
0064: */
0065: public class BaseSite implements Site {
0066: /** Our log (commons). */
0067: private static Log M_log = LogFactory.getLog(BaseSite.class);
0068:
0069: /** A fixed class serian number. */
0070: private static final long serialVersionUID = 1L;
0071:
0072: /** The event code for this edit. */
0073: protected String m_event = null;
0074:
0075: /** Active flag. */
0076: protected boolean m_active = false;
0077:
0078: /** List of groups deleted in this edit pass. */
0079: protected Collection m_deletedGroups = new Vector();
0080:
0081: /** The site id. */
0082: protected String m_id = null;
0083:
0084: /** The site title. */
0085: protected String m_title = null;
0086:
0087: /** The site short description. */
0088: protected String m_shortDescription = null;
0089:
0090: /** The site description. */
0091: protected String m_description = null;
0092:
0093: /** The name of the role given to users who join a joinable site. */
0094: protected String m_joinerRole = null;
0095:
0096: /** Is this site joinable. */
0097: protected boolean m_joinable = false;
0098:
0099: /** Published or not. */
0100: protected boolean m_published = false;
0101:
0102: /** The icon url. */
0103: protected String m_icon = null;
0104:
0105: /** The site info url. */
0106: protected String m_info = null;
0107:
0108: /** The properties. */
0109: protected ResourcePropertiesEdit m_properties = null;
0110:
0111: /** The list of site pages for this site. */
0112: protected ResourceVector m_pages = null;
0113:
0114: /** Set true while the pages have not yet been read in for a site. */
0115: protected boolean m_pagesLazy = false;
0116:
0117: /** The skin to use for this site. */
0118: protected String m_skin = null;
0119:
0120: /** The pubView flag. */
0121: protected boolean m_pubView = false;
0122:
0123: /** The site type. */
0124: protected String m_type = null;
0125:
0126: /** The created user id. */
0127: protected String m_createdUserId = null;
0128:
0129: /** The last modified user id. */
0130: protected String m_lastModifiedUserId = null;
0131:
0132: /** The time created. */
0133: protected Time m_createdTime = null;
0134:
0135: /** The time last modified. */
0136: protected Time m_lastModifiedTime = null;
0137:
0138: /** The list of site groups for this site. */
0139: protected ResourceVector m_groups = null;
0140:
0141: /** Set true while the groups have not yet been read in for a site. */
0142: protected boolean m_groupsLazy = false;
0143:
0144: /** The azg from the AuthzGroupService that is my AuthzGroup impl. */
0145: protected AuthzGroup m_azg = null;
0146:
0147: /** Set to true if we have changed our azg, so it need to be written back on save. */
0148: protected boolean m_azgChanged = false;
0149:
0150: /** Set to true to use the site's page order, or false to let a toolOrder override the page order. */
0151: protected boolean m_customPageOrdered = false;
0152:
0153: /**
0154: * Construct.
0155: *
0156: * @param id
0157: * The site id.
0158: */
0159: public BaseSite(String id) {
0160: m_id = id;
0161:
0162: // setup for properties
0163: m_properties = new BaseResourcePropertiesEdit();
0164:
0165: // set up the page list
0166: m_pages = new ResourceVector();
0167:
0168: // set up the groups collection
0169: m_groups = new ResourceVector();
0170:
0171: // if the id is not null (a new site, rather than a reconstruction)
0172: // add the automatic (live) properties
0173: if (m_id != null)
0174: ((BaseSiteService) (SiteService.getInstance()))
0175: .addLiveProperties(this );
0176: }
0177:
0178: /**
0179: * Construct from another Site, exact.
0180: *
0181: * @param site
0182: * The other site to copy values from.
0183: * @param exact
0184: * If true, we copy ids - else we generate new ones for site, page and tools.
0185: */
0186: public BaseSite(Site other) {
0187: BaseSite bOther = (BaseSite) other;
0188: set(bOther, true);
0189: }
0190:
0191: /**
0192: * Construct from another Site.
0193: *
0194: * @param site
0195: * The other site to copy values from.
0196: * @param exact
0197: * If true, we copy ids - else we generate new ones for site, page and tools.
0198: */
0199: public BaseSite(Site other, boolean exact) {
0200: BaseSite bOther = (BaseSite) other;
0201: set(bOther, exact);
0202: }
0203:
0204: /**
0205: * Construct from an existing definition, in xml.
0206: *
0207: * @param el
0208: * The message in XML in a DOM element.
0209: */
0210: public BaseSite(Element el) {
0211: // setup for properties
0212: m_properties = new BaseResourcePropertiesEdit();
0213:
0214: // setup for page list
0215: m_pages = new ResourceVector();
0216:
0217: // setup for the groups list
0218: m_groups = new ResourceVector();
0219:
0220: m_id = el.getAttribute("id");
0221: m_title = StringUtil.trimToNull(el.getAttribute("title"));
0222:
0223: // description might be encripted
0224: m_description = StringUtil.trimToNull(el
0225: .getAttribute("description"));
0226: if (m_description == null) {
0227: m_description = StringUtil.trimToNull(Xml.decodeAttribute(
0228: el, "description-enc"));
0229: }
0230:
0231: // short description might be encripted
0232: m_shortDescription = StringUtil.trimToNull(el
0233: .getAttribute("short-description"));
0234: if (m_shortDescription == null) {
0235: m_shortDescription = StringUtil.trimToNull(Xml
0236: .decodeAttribute(el, "short-description-enc"));
0237: }
0238:
0239: m_joinable = Boolean.valueOf(el.getAttribute("joinable"))
0240: .booleanValue();
0241: m_joinerRole = StringUtil.trimToNull(el
0242: .getAttribute("joiner-role"));
0243:
0244: String published = StringUtil.trimToNull(el
0245: .getAttribute("published"));
0246: if (published == null) {
0247: // read the old "status" (this file 1.42 and before) 1-un 2-pub
0248: published = StringUtil
0249: .trimToNull(el.getAttribute("status"));
0250: if (published != null) {
0251: published = Boolean.valueOf("2".equals(published))
0252: .toString();
0253: }
0254: }
0255:
0256: m_published = Boolean.valueOf(published).booleanValue();
0257:
0258: m_icon = StringUtil.trimToNull(el.getAttribute("icon"));
0259: m_info = StringUtil.trimToNull(el.getAttribute("info"));
0260: m_skin = StringUtil.trimToNull(el.getAttribute("skin"));
0261:
0262: m_createdUserId = StringUtil.trimToNull(el
0263: .getAttribute("created-id"));
0264: m_lastModifiedUserId = StringUtil.trimToNull(el
0265: .getAttribute("modified-id"));
0266:
0267: String time = StringUtil.trimToNull(el
0268: .getAttribute("created-time"));
0269: if (time != null) {
0270: m_createdTime = TimeService.newTimeGmt(time);
0271: }
0272:
0273: time = StringUtil.trimToNull(el.getAttribute("modified-time"));
0274: if (time != null) {
0275: m_lastModifiedTime = TimeService.newTimeGmt(time);
0276: }
0277:
0278: String customOrder = StringUtil.trimToNull(el
0279: .getAttribute("customPageOrdered"));
0280: if (customOrder == null) {
0281: m_customPageOrdered = false;
0282: } else {
0283: m_customPageOrdered = Boolean.valueOf(customOrder)
0284: .booleanValue();
0285: }
0286:
0287: // get pubView setting - but old versions (pre 1.42 of this file) won't have it and will have a property instead
0288: String pubViewValue = StringUtil.trimToNull(el
0289: .getAttribute("pubView"));
0290:
0291: // get the type - but old versions (pre 1.42 of this file) won't have it and will have a property instead
0292: String typeValue = StringUtil.trimToNull(el
0293: .getAttribute("type"));
0294:
0295: // the children (properties and page list)
0296: NodeList children = el.getChildNodes();
0297: for (int i = 0; i < children.getLength(); i++) {
0298: Node child = children.item(i);
0299: if (child.getNodeType() != Node.ELEMENT_NODE)
0300: continue;
0301: Element element = (Element) child;
0302:
0303: // look for properties
0304: if (element.getTagName().equals("properties")) {
0305: // re-create properties
0306: m_properties = new BaseResourcePropertiesEdit(element);
0307:
0308: // look for pubview (pre 1.42 of this file) in properties
0309: if (pubViewValue == null) {
0310: pubViewValue = m_properties
0311: .getProperty("CTNG:site-include");
0312: if (pubViewValue == null) {
0313: pubViewValue = m_properties
0314: .getProperty("site-include");
0315: }
0316: }
0317: m_properties.removeProperty("CTNG:site-include");
0318: m_properties.removeProperty("site-include");
0319:
0320: // look for type (pre 1.42 of this file) in properties (two possibilities)
0321: if (typeValue == null) {
0322: typeValue = m_properties
0323: .getProperty("SAKAI:site-type");
0324: if (typeValue == null) {
0325: typeValue = m_properties
0326: .getProperty("CTNG:site-type");
0327: }
0328: }
0329: m_properties.removeProperty("SAKAI:site-type");
0330: m_properties.removeProperty("CTNG:site-type");
0331:
0332: // look for short description (pre 1.42 of this file) in properties
0333: if (m_shortDescription == null) {
0334: m_shortDescription = m_properties
0335: .getProperty("CTNG:short-description");
0336:
0337: if (m_shortDescription == null) {
0338: m_shortDescription = m_properties
0339: .getProperty("short-description");
0340: }
0341: }
0342: m_properties.removeProperty("CTNG:short-description");
0343: m_properties.removeProperty("short-description");
0344:
0345: // pull out some properties into fields to convert old (pre 1.42) versions
0346: if (m_createdUserId == null) {
0347: m_createdUserId = m_properties
0348: .getProperty("CHEF:creator");
0349: }
0350: if (m_lastModifiedUserId == null) {
0351: m_lastModifiedUserId = m_properties
0352: .getProperty("CHEF:modifiedby");
0353: }
0354: if (m_createdTime == null) {
0355: try {
0356: m_createdTime = m_properties
0357: .getTimeProperty("DAV:creationdate");
0358: } catch (Exception ignore) {
0359: }
0360: }
0361: if (m_lastModifiedTime == null) {
0362: try {
0363: m_lastModifiedTime = m_properties
0364: .getTimeProperty("DAV:getlastmodified");
0365: } catch (Exception ignore) {
0366: }
0367: }
0368: m_properties.removeProperty("CHEF:creator");
0369: m_properties.removeProperty("CHEF:modifiedby");
0370: m_properties.removeProperty("DAV:creationdate");
0371: m_properties.removeProperty("DAV:getlastmodified");
0372: }
0373:
0374: // look for the page list
0375: else if (element.getTagName().equals("pages")) {
0376: NodeList pagesNodes = element.getChildNodes();
0377: for (int p = 0; p < pagesNodes.getLength(); p++) {
0378: Node pageNode = pagesNodes.item(p);
0379: if (pageNode.getNodeType() != Node.ELEMENT_NODE)
0380: continue;
0381: Element pageEl = (Element) pageNode;
0382: if (!pageEl.getTagName().equals("page"))
0383: continue;
0384:
0385: BaseSitePage page = new BaseSitePage(pageEl, this );
0386: m_pages.add(page);
0387: }
0388:
0389: // TODO: else if ( "groups")
0390: }
0391: }
0392:
0393: // set the pubview, now it's found in either the attribute or the properties
0394: if (pubViewValue != null) {
0395: m_pubView = Boolean.valueOf(pubViewValue).booleanValue();
0396: } else {
0397: m_pubView = false;
0398: }
0399:
0400: // set the type, now it's found in either the attribute or the properties
0401: m_type = typeValue;
0402: }
0403:
0404: /**
0405: * ReConstruct.
0406: *
0407: * @param id
0408: * @param title
0409: * @param type
0410: * @param shortDesc
0411: * @param description
0412: * @param iconUrl
0413: * @param infoUrl
0414: * @param skin
0415: * @param published
0416: * @param joinable
0417: * @param pubView
0418: * @param joinRole
0419: * @param isSpecial
0420: * @param isUser
0421: * @param createdBy
0422: * @param createdOn
0423: * @param modifiedBy
0424: * @param modifiedOn
0425: */
0426: public BaseSite(String id, String title, String type,
0427: String shortDesc, String description, String iconUrl,
0428: String infoUrl, String skin, boolean published,
0429: boolean joinable, boolean pubView, String joinRole,
0430: boolean isSpecial, boolean isUser, String createdBy,
0431: Time createdOn, String modifiedBy, Time modifiedOn,
0432: boolean customPageOrdered) {
0433: // setup for properties
0434: m_properties = new BaseResourcePropertiesEdit();
0435:
0436: // set up the page list
0437: m_pages = new ResourceVector();
0438:
0439: // set up the groups collection
0440: m_groups = new ResourceVector();
0441:
0442: m_id = id;
0443: m_title = title;
0444: m_type = type;
0445: m_shortDescription = shortDesc;
0446: m_description = description;
0447: m_icon = iconUrl;
0448: m_info = infoUrl;
0449: m_skin = skin;
0450: m_published = published;
0451: m_joinable = joinable;
0452: m_pubView = pubView;
0453: m_joinerRole = joinRole;
0454: // TODO: isSpecial
0455: // TODO: isUser
0456: m_createdUserId = createdBy;
0457: m_lastModifiedUserId = modifiedBy;
0458: m_createdTime = createdOn;
0459: m_lastModifiedTime = modifiedOn;
0460: m_customPageOrdered = customPageOrdered;
0461:
0462: // setup for properties, but mark them lazy since we have not yet established them from data
0463: ((BaseResourcePropertiesEdit) m_properties).setLazy(true);
0464:
0465: m_pagesLazy = true;
0466: m_groupsLazy = true;
0467: }
0468:
0469: /**
0470: * Set me to be a deep copy of other (all but my id.)
0471: *
0472: * @param bOther
0473: * the other to copy.
0474: * @param exact
0475: * If true, we copy ids - else we generate new ones for site, page and tools.
0476: */
0477: protected void set(BaseSite other, boolean exact) {
0478: // if exact, set the id, else assume the id was already set
0479: if (exact) {
0480: m_id = other.m_id;
0481: }
0482:
0483: m_title = other.m_title;
0484: m_shortDescription = other.m_shortDescription;
0485: m_description = other.m_description;
0486: m_joinable = other.m_joinable;
0487: m_joinerRole = other.m_joinerRole;
0488: m_published = other.m_published;
0489: m_icon = other.m_icon;
0490: m_info = other.m_info;
0491: m_skin = other.m_skin;
0492: m_type = other.m_type;
0493: m_pubView = other.m_pubView;
0494: m_customPageOrdered = other.m_customPageOrdered;
0495: if (exact) {
0496: m_createdUserId = other.m_createdUserId;
0497: } else {
0498: m_createdUserId = UserDirectoryService.getCurrentUser()
0499: .getId();
0500: }
0501: m_lastModifiedUserId = other.m_lastModifiedUserId;
0502: if (other.m_createdTime != null)
0503: m_createdTime = (Time) other.m_createdTime.clone();
0504: if (other.m_lastModifiedTime != null)
0505: m_lastModifiedTime = (Time) other.m_lastModifiedTime
0506: .clone();
0507:
0508: m_properties = new BaseResourcePropertiesEdit();
0509: ResourceProperties pOther = other.getProperties();
0510: if (exact) {
0511: m_properties.addAll(pOther);
0512: } else {
0513: Iterator l = pOther.getPropertyNames();
0514: while (l.hasNext()) {
0515: String pOtherName = (String) l.next();
0516: m_properties.addProperty(pOtherName, pOther
0517: .getProperty(pOtherName).replaceAll(
0518: other.getId(), getId()));
0519: }
0520: }
0521: ((BaseResourcePropertiesEdit) m_properties)
0522: .setLazy(((BaseResourceProperties) other
0523: .getProperties()).isLazy());
0524:
0525: // deep copy the pages
0526: m_pages = new ResourceVector();
0527: for (Iterator iPages = other.getPages().iterator(); iPages
0528: .hasNext();) {
0529: BaseSitePage page = (BaseSitePage) iPages.next();
0530: m_pages.add(new BaseSitePage(page, this , exact));
0531: }
0532: m_pagesLazy = other.m_pagesLazy;
0533:
0534: // deep copy the groups
0535: m_groups = new ResourceVector();
0536: for (Iterator iGroups = other.getGroups().iterator(); iGroups
0537: .hasNext();) {
0538: Group group = (Group) iGroups.next();
0539: m_groups.add(new BaseGroup(group, this , exact));
0540: }
0541: m_groupsLazy = other.m_groupsLazy;
0542: }
0543:
0544: /**
0545: * @inheritDoc
0546: */
0547: public String getId() {
0548: if (m_id == null)
0549: return "";
0550: return m_id;
0551: }
0552:
0553: /**
0554: * @inheritDoc
0555: */
0556: public String getUrl() {
0557: return ((BaseSiteService) (SiteService.getInstance()))
0558: .serverConfigurationService().getPortalUrl()
0559: + "/site/" + m_id;
0560: }
0561:
0562: /**
0563: * @inheritDoc
0564: */
0565: public String getReference() {
0566: return ((BaseSiteService) (SiteService.getInstance()))
0567: .siteReference(m_id);
0568: }
0569:
0570: /**
0571: * @inheritDoc
0572: */
0573: public String getReference(String rootProperty) {
0574: return getReference();
0575: }
0576:
0577: /**
0578: * @inheritDoc
0579: */
0580: public String getUrl(String rootProperty) {
0581: return getUrl();
0582: }
0583:
0584: /**
0585: * @inheritDoc
0586: */
0587: public ResourceProperties getProperties() {
0588: // if lazy, resolve
0589: if (((BaseResourceProperties) m_properties).isLazy()) {
0590: ((BaseSiteService) (SiteService.getInstance())).m_storage
0591: .readSiteProperties(this , m_properties);
0592: ((BaseResourcePropertiesEdit) m_properties).setLazy(false);
0593: }
0594:
0595: return m_properties;
0596: }
0597:
0598: /**
0599: * {@inheritDoc}
0600: */
0601: public User getCreatedBy() {
0602: try {
0603: return UserDirectoryService.getUser(m_createdUserId);
0604: } catch (Exception e) {
0605: return UserDirectoryService.getAnonymousUser();
0606: }
0607: }
0608:
0609: /**
0610: * {@inheritDoc}
0611: */
0612: public User getModifiedBy() {
0613: try {
0614: return UserDirectoryService.getUser(m_lastModifiedUserId);
0615: } catch (Exception e) {
0616: return UserDirectoryService.getAnonymousUser();
0617: }
0618: }
0619:
0620: /**
0621: * {@inheritDoc}
0622: */
0623: public Time getCreatedTime() {
0624: return m_createdTime;
0625: }
0626:
0627: /**
0628: * {@inheritDoc}
0629: */
0630: public Time getModifiedTime() {
0631: return m_lastModifiedTime;
0632: }
0633:
0634: /**
0635: * @inheritDoc
0636: */
0637: public String getTitle() {
0638: // if set here, use the setting
0639: if (m_title != null)
0640: return m_title;
0641:
0642: // if not otherwise set, use the id
0643: return getId();
0644: }
0645:
0646: /**
0647: * @inheritDoc
0648: */
0649: public String getShortDescription() {
0650: return m_shortDescription;
0651: }
0652:
0653: /**
0654: * @inheritDoc
0655: */
0656: public String getDescription() {
0657: return m_description;
0658: }
0659:
0660: /**
0661: * @inheritDoc
0662: */
0663: public boolean isJoinable() {
0664: return m_joinable;
0665: }
0666:
0667: /**
0668: * @inheritDoc
0669: */
0670: public String getJoinerRole() {
0671: return m_joinerRole;
0672: }
0673:
0674: /**
0675: * {@inheritDoc}
0676: */
0677: public boolean isPublished() {
0678: return m_published;
0679: }
0680:
0681: /**
0682: * @inheritDoc
0683: */
0684: public String getSkin() {
0685: return m_skin;
0686: }
0687:
0688: /**
0689: * @inheritDoc
0690: */
0691: public String getIconUrl() {
0692: return m_icon;
0693: }
0694:
0695: /**
0696: * {@inheritDoc}
0697: */
0698: public String getIconUrlFull() {
0699: return ((BaseSiteService) (SiteService.getInstance()))
0700: .convertReferenceUrl(m_icon);
0701: }
0702:
0703: /**
0704: * @inheritDoc
0705: */
0706: public String getInfoUrl() {
0707: return m_info;
0708: }
0709:
0710: /**
0711: * {@inheritDoc}
0712: */
0713: public String getInfoUrlFull() {
0714: if (m_info == null)
0715: return null;
0716:
0717: return ((BaseSiteService) (SiteService.getInstance()))
0718: .convertReferenceUrl(m_info);
0719: }
0720:
0721: /**
0722: * {@inheritDoc}
0723: */
0724: public List getPages() {
0725: if (m_pagesLazy) {
0726: ((BaseSiteService) (SiteService.getInstance())).m_storage
0727: .readSitePages(this , m_pages);
0728: m_pagesLazy = false;
0729: }
0730:
0731: return m_pages;
0732: }
0733:
0734: /**
0735: * {@inheritDoc}
0736: */
0737: public Collection getGroups() {
0738: if (m_groupsLazy) {
0739: ((BaseSiteService) (SiteService.getInstance())).m_storage
0740: .readSiteGroups(this , m_groups);
0741: m_groupsLazy = false;
0742: }
0743:
0744: return m_groups;
0745: }
0746:
0747: /**
0748: * {@inheritDoc}
0749: */
0750: public Collection getGroupsWithMember(String userId) {
0751: Collection groups = getGroups();
0752: Collection rv = new Vector();
0753: for (Iterator i = groups.iterator(); i.hasNext();) {
0754: Group g = (Group) i.next();
0755: Member m = g.getMember(userId);
0756: if ((m != null) && (m.isActive())) {
0757: rv.add(g);
0758: }
0759: }
0760:
0761: return rv;
0762: }
0763:
0764: /**
0765: * {@inheritDoc}
0766: */
0767: public Collection getGroupsWithMemberHasRole(String userId,
0768: String role) {
0769: Collection groups = getGroups();
0770: Collection rv = new Vector();
0771: for (Iterator i = groups.iterator(); i.hasNext();) {
0772: Group g = (Group) i.next();
0773: Member m = g.getMember(userId);
0774: if ((m != null) && (m.isActive())
0775: && (m.getRole().getId().equals(role))) {
0776: rv.add(g);
0777: }
0778: }
0779:
0780: return rv;
0781: }
0782:
0783: /**
0784: * {@inheritDoc}
0785: */
0786: public boolean hasGroups() {
0787: Collection groups = getGroups();
0788: return !groups.isEmpty();
0789: }
0790:
0791: /**
0792: * {@inheritDoc}
0793: */
0794: public void loadAll() {
0795: // first, pages
0796: getPages();
0797:
0798: // next, tools from all pages, all at once
0799: ((BaseSiteService) (SiteService.getInstance())).m_storage
0800: .readSiteTools(this );
0801:
0802: // get groups, all at once
0803: getGroups();
0804:
0805: // now all properties
0806: ((BaseSiteService) (SiteService.getInstance())).m_storage
0807: .readAllSiteProperties(this );
0808: }
0809:
0810: /**
0811: * {@inheritDoc}
0812: */
0813: public List getOrderedPages() {
0814: // if we are set to use our custom page order, do so
0815: if (m_customPageOrdered)
0816: return getPages();
0817:
0818: List order = ((BaseSiteService) (SiteService.getInstance()))
0819: .serverConfigurationService().getToolOrder(getType());
0820: if (order.isEmpty())
0821: return getPages();
0822:
0823: // get a copy we can modify without changing the site!
0824: List pages = new Vector(getPages());
0825:
0826: // find any pages that include the tool type for each tool in the ordering, move them into the newOrder and remove from the old
0827: List newOrder = new Vector();
0828:
0829: // for each entry in the order
0830: for (Iterator i = order.iterator(); i.hasNext();) {
0831: String toolId = (String) i.next();
0832:
0833: // find any pages that have this tool
0834: for (Iterator p = pages.iterator(); p.hasNext();) {
0835: SitePage page = (SitePage) p.next();
0836: List tools = page.getTools();
0837: for (Iterator t = tools.iterator(); t.hasNext();) {
0838: ToolConfiguration tool = (ToolConfiguration) t
0839: .next();
0840: if (tool.getToolId().equals(toolId)) {
0841: // this page has this tool, so move it from the pages to the newOrder
0842: newOrder.add(page);
0843: p.remove();
0844: break;
0845: }
0846: }
0847: }
0848: }
0849:
0850: // add any remaining
0851: newOrder.addAll(pages);
0852:
0853: return newOrder;
0854: }
0855:
0856: /**
0857: * {@inheritDoc}
0858: */
0859: public SitePage getPage(String id) {
0860: return (SitePage) ((ResourceVector) getPages()).getById(id);
0861: }
0862:
0863: /**
0864: * {@inheritDoc}
0865: */
0866: public ToolConfiguration getTool(String id) {
0867: // search the pages
0868: for (Iterator iPages = getPages().iterator(); iPages.hasNext();) {
0869: SitePage page = (SitePage) iPages.next();
0870: ToolConfiguration tool = page.getTool(id);
0871:
0872: if (tool != null)
0873: return tool;
0874: }
0875:
0876: return null;
0877: }
0878:
0879: /**
0880: * {@inheritDoc}
0881: */
0882: public Collection getTools(String commonToolId) {
0883: String[] toolIds = new String[1];
0884: toolIds[0] = commonToolId;
0885: return getTools(toolIds);
0886: }
0887:
0888: /**
0889: * {@inheritDoc}
0890: */
0891: public ToolConfiguration getToolForCommonId(String commonToolId) {
0892: Collection col = getTools(commonToolId);
0893: if (col == null)
0894: return null;
0895: if (col.size() == 0)
0896: return null;
0897: return (ToolConfiguration) col.iterator().next(); // Return first element
0898: }
0899:
0900: /**
0901: * {@inheritDoc}
0902: */
0903: public Collection getTools(String[] toolIds) {
0904: List rv = new Vector();
0905: if ((toolIds == null) || (toolIds.length == 0))
0906: return rv;
0907:
0908: // search the pages
0909: for (Iterator iPages = getPages().iterator(); iPages.hasNext();) {
0910: SitePage page = (SitePage) iPages.next();
0911: rv.addAll(page.getTools(toolIds));
0912: }
0913:
0914: return rv;
0915: }
0916:
0917: /**
0918: * {@inheritDoc}
0919: */
0920: public Group getGroup(String id) {
0921: if (id == null)
0922: return null;
0923:
0924: // if this is a reference, starting with a "/", parse it, make sure it's a group, in this site, and pull the id
0925: if (id.startsWith(Entity.SEPARATOR)) {
0926: Reference ref = ((BaseSiteService) (SiteService
0927: .getInstance())).entityManager().newReference(id);
0928: if ((SiteService.APPLICATION_ID.equals(ref.getType()))
0929: && (SiteService.GROUP_SUBTYPE.equals(ref
0930: .getSubType()))
0931: && (m_id.equals(ref.getContainer()))) {
0932: return (Group) ((ResourceVector) getGroups())
0933: .getById(ref.getId());
0934: }
0935:
0936: return null;
0937: }
0938:
0939: return (Group) ((ResourceVector) getGroups()).getById(id);
0940: }
0941:
0942: /**
0943: * {@inheritDoc}
0944: */
0945: public String getType() {
0946: return m_type;
0947: }
0948:
0949: /**
0950: * @inheritDoc
0951: */
0952: public boolean isType(Object type) {
0953: if (type == null)
0954: return true;
0955:
0956: String myType = getType();
0957:
0958: if (type instanceof String[]) {
0959: for (int i = 0; i < ((String[]) type).length; i++) {
0960: String test = ((String[]) type)[i];
0961: if ((test != null) && (test.equals(myType))) {
0962: return true;
0963: }
0964: }
0965: }
0966:
0967: else if (type instanceof Collection) {
0968: return ((Collection) type).contains(myType);
0969: }
0970:
0971: else if (type instanceof String) {
0972: return type.equals(myType);
0973: }
0974:
0975: return false;
0976: }
0977:
0978: /**
0979: * @inheritDoc
0980: */
0981: public boolean equals(Object obj) {
0982: if (obj instanceof Site) {
0983: return ((Site) obj).getId().equals(getId());
0984: }
0985:
0986: // compare to strings as id
0987: if (obj instanceof String) {
0988: return ((String) obj).equals(getId());
0989: }
0990:
0991: return false;
0992: }
0993:
0994: /**
0995: * @inheritDoc
0996: */
0997: public int hashCode() {
0998: return getId().hashCode();
0999: }
1000:
1001: /**
1002: * @inheritDoc
1003: */
1004: public int compareTo(Object obj) {
1005: if (!(obj instanceof Site))
1006: throw new ClassCastException();
1007:
1008: // if the object are the same, say so
1009: if (obj == this )
1010: return 0;
1011:
1012: // start the compare by comparing their sort names
1013: int compare = getTitle().compareTo(((Site) obj).getTitle());
1014:
1015: // if these are the same
1016: if (compare == 0) {
1017: // sort based on (unique) id
1018: compare = getId().compareTo(((Site) obj).getId());
1019: }
1020:
1021: return compare;
1022: }
1023:
1024: /**
1025: * {@inheritDoc}
1026: */
1027: public boolean isPubView() {
1028: return m_pubView;
1029: }
1030:
1031: /**
1032: * {@inheritDoc}
1033: */
1034: public Element toXml(Document doc, Stack stack) {
1035: Element site = doc.createElement("site");
1036: if (stack.isEmpty()) {
1037: doc.appendChild(site);
1038: } else {
1039: ((Element) stack.peek()).appendChild(site);
1040: }
1041:
1042: site.setAttribute("id", getId());
1043: if (m_title != null)
1044: site.setAttribute("title", m_title);
1045:
1046: // encode the short description
1047: if (m_shortDescription != null)
1048: Xml.encodeAttribute(site, "short-description-enc",
1049: m_shortDescription);
1050:
1051: // encode the description
1052: if (m_description != null)
1053: Xml.encodeAttribute(site, "description-enc", m_description);
1054:
1055: site.setAttribute("joinable", new Boolean(m_joinable)
1056: .toString());
1057: if (m_joinerRole != null)
1058: site.setAttribute("joiner-role", m_joinerRole);
1059: site.setAttribute("published", Boolean.valueOf(m_published)
1060: .toString());
1061: if (m_icon != null)
1062: site.setAttribute("icon", m_icon);
1063: if (m_info != null)
1064: site.setAttribute("info", m_info);
1065: if (m_skin != null)
1066: site.setAttribute("skin", m_skin);
1067: site.setAttribute("pubView", Boolean.valueOf(m_pubView)
1068: .toString());
1069: site.setAttribute("customPageOrdered", Boolean.valueOf(
1070: m_customPageOrdered).toString());
1071: site.setAttribute("type", m_type);
1072:
1073: site.setAttribute("created-id", m_createdUserId);
1074: site.setAttribute("modified-id", m_lastModifiedUserId);
1075: site.setAttribute("created-time", m_createdTime.toString());
1076: site.setAttribute("modified-time", m_lastModifiedTime
1077: .toString());
1078:
1079: // properties
1080: stack.push(site);
1081: getProperties().toXml(doc, stack);
1082: stack.pop();
1083:
1084: // site pages
1085: Element list = doc.createElement("pages");
1086: site.appendChild(list);
1087: stack.push(list);
1088: for (Iterator iPages = getPages().iterator(); iPages.hasNext();) {
1089: BaseSitePage page = (BaseSitePage) iPages.next();
1090: page.toXml(doc, stack);
1091: }
1092: stack.pop();
1093:
1094: // TODO: site groups
1095:
1096: return site;
1097: }
1098:
1099: /**
1100: * {@inheritDoc}
1101: */
1102: public void setTitle(String title) {
1103: m_title = StringUtil.trimToNull(title);
1104: }
1105:
1106: /**
1107: * {@inheritDoc}
1108: */
1109: public void setShortDescription(String shortDescripion) {
1110: m_shortDescription = StringUtil.trimToNull(shortDescripion);
1111: }
1112:
1113: /**
1114: * {@inheritDoc}
1115: */
1116: public void setDescription(String description) {
1117: m_description = StringUtil.trimToNull(description);
1118: }
1119:
1120: /**
1121: * {@inheritDoc}
1122: */
1123: public void setJoinable(boolean joinable) {
1124: m_joinable = joinable;
1125: }
1126:
1127: /**
1128: * {@inheritDoc}
1129: */
1130: public void setJoinerRole(String role) {
1131: m_joinerRole = role;
1132: }
1133:
1134: /**
1135: * {@inheritDoc}
1136: */
1137: public void setPublished(boolean published) {
1138: m_published = published;
1139:
1140: }
1141:
1142: /**
1143: * {@inheritDoc}
1144: */
1145: public void setSkin(String skin) {
1146: m_skin = skin;
1147: }
1148:
1149: /**
1150: * {@inheritDoc}
1151: */
1152: public void setIconUrl(String url) {
1153: m_icon = StringUtil.trimToNull(url);
1154: }
1155:
1156: /**
1157: * {@inheritDoc}
1158: */
1159: public void setInfoUrl(String url) {
1160: m_info = StringUtil.trimToNull(url);
1161: }
1162:
1163: /**
1164: * {@inheritDoc}
1165: */
1166: public SitePage addPage() {
1167: BaseSitePage page = new BaseSitePage(this );
1168: getPages().add(page);
1169:
1170: return page;
1171: }
1172:
1173: /**
1174: * @inheritDoc
1175: */
1176: public void removePage(SitePage page) {
1177: getPages().remove(page);
1178: }
1179:
1180: /**
1181: * Access the event code for this edit.
1182: *
1183: * @return The event code for this edit.
1184: */
1185: protected String getEvent() {
1186: return m_event;
1187: }
1188:
1189: /**
1190: * Set the event code for this edit.
1191: *
1192: * @param event
1193: * The event code for this edit.
1194: */
1195: protected void setEvent(String event) {
1196: m_event = event;
1197: }
1198:
1199: /**
1200: * @inheritDoc
1201: */
1202: public ResourcePropertiesEdit getPropertiesEdit() {
1203: // if lazy, resolve
1204: if (((BaseResourceProperties) m_properties).isLazy()) {
1205: ((BaseSiteService) (SiteService.getInstance())).m_storage
1206: .readSiteProperties(this , m_properties);
1207: ((BaseResourcePropertiesEdit) m_properties).setLazy(false);
1208: }
1209:
1210: return m_properties;
1211: }
1212:
1213: /**
1214: * {@inheritDoc}
1215: */
1216: public void setType(String type) {
1217: m_type = type;
1218: }
1219:
1220: /**
1221: * {@inheritDoc}
1222: */
1223: public void setPubView(boolean pubView) {
1224: m_pubView = pubView;
1225:
1226: }
1227:
1228: /**
1229: * {@inheritDoc}
1230: */
1231: public boolean isCustomPageOrdered() {
1232: return m_customPageOrdered;
1233: }
1234:
1235: /**
1236: * {@inheritDoc}
1237: */
1238: public void setCustomPageOrdered(boolean setting) {
1239: m_customPageOrdered = setting;
1240: }
1241:
1242: /**
1243: * Enable editing.
1244: */
1245: protected void activate() {
1246: m_active = true;
1247: }
1248:
1249: /**
1250: * @inheritDoc
1251: */
1252: public boolean isActiveEdit() {
1253: return m_active;
1254: }
1255:
1256: /**
1257: * Close the edit object - it cannot be used after this.
1258: */
1259: protected void closeEdit() {
1260: m_active = false;
1261: }
1262:
1263: /**
1264: * @inheritDoc
1265: */
1266: public void regenerateIds() {
1267: // deep copy the pages
1268: ResourceVector newPages = new ResourceVector();
1269: for (Iterator iPages = getPages().iterator(); iPages.hasNext();) {
1270: BaseSitePage page = (BaseSitePage) iPages.next();
1271: newPages.add(new BaseSitePage(page, this , false));
1272: }
1273:
1274: m_pages = newPages;
1275: }
1276:
1277: /**
1278: * {@inheritDoc}
1279: */
1280: public Group addGroup() {
1281: Group rv = new BaseGroup(this );
1282: m_groups.add(rv);
1283:
1284: return rv;
1285: }
1286:
1287: /**
1288: * {@inheritDoc}
1289: */
1290: public void removeGroup(Group group) {
1291: // remove it
1292: m_groups.remove(group);
1293:
1294: // track so we can clean up related on commit
1295: m_deletedGroups.add(group);
1296: }
1297:
1298: /**
1299: * Access (find if needed) the azg from the AuthzGroupService that implements my grouping.
1300: * @return My azg.
1301: */
1302: protected AuthzGroup getAzg() {
1303: if (m_azg == null) {
1304: try {
1305: m_azg = AuthzGroupService.getAuthzGroup(getReference());
1306: } catch (GroupNotDefinedException e) {
1307: try {
1308: // create the site's azg, but don't store it yet (that happens if save is called)
1309:
1310: // try the site created-by user for the maintain role in the site
1311: String userId = getCreatedBy().getId();
1312: if (userId != null) {
1313: // make sure it's valid
1314: try {
1315: UserDirectoryService.getUser(userId);
1316: } catch (UserNotDefinedException e1) {
1317: userId = null;
1318: }
1319: }
1320:
1321: // use the current user if needed
1322: if (userId == null) {
1323: User user = UserDirectoryService
1324: .getCurrentUser();
1325: userId = user.getId();
1326: }
1327:
1328: // find the template for the new azg
1329: String groupAzgTemplate = ((BaseSiteService) (SiteService
1330: .getInstance())).siteAzgTemplate(this );
1331: AuthzGroup template = null;
1332: try {
1333: template = AuthzGroupService
1334: .getAuthzGroup(groupAzgTemplate);
1335: } catch (Exception e1) {
1336: try {
1337: // if the template is not defined, try the fall back template
1338: template = AuthzGroupService
1339: .getAuthzGroup("!site.template");
1340: } catch (Exception e2) {
1341: }
1342: }
1343:
1344: m_azg = AuthzGroupService.newAuthzGroup(
1345: getReference(), template, userId);
1346: m_azgChanged = true;
1347: } catch (Throwable t) {
1348: M_log.warn("getAzg: " + t);
1349: }
1350: }
1351: }
1352:
1353: return m_azg;
1354: }
1355:
1356: public void addMember(String userId, String roleId, boolean active,
1357: boolean provided) {
1358: m_azgChanged = true;
1359: getAzg().addMember(userId, roleId, active, provided);
1360: }
1361:
1362: public Role addRole(String id) throws RoleAlreadyDefinedException {
1363: m_azgChanged = true;
1364: return getAzg().addRole(id);
1365: }
1366:
1367: public Role addRole(String id, Role other)
1368: throws RoleAlreadyDefinedException {
1369: m_azgChanged = true;
1370: return getAzg().addRole(id, other);
1371: }
1372:
1373: public String getMaintainRole() {
1374: return getAzg().getMaintainRole();
1375: }
1376:
1377: public Member getMember(String userId) {
1378: return getAzg().getMember(userId);
1379: }
1380:
1381: public Set getMembers() {
1382: return getAzg().getMembers();
1383: }
1384:
1385: public String getProviderGroupId() {
1386: return getAzg().getProviderGroupId();
1387: }
1388:
1389: public Role getRole(String id) {
1390: return getAzg().getRole(id);
1391: }
1392:
1393: public Set getRoles() {
1394: return getAzg().getRoles();
1395: }
1396:
1397: public Set getRolesIsAllowed(String function) {
1398: return getAzg().getRolesIsAllowed(function);
1399: }
1400:
1401: public Role getUserRole(String userId) {
1402: return getAzg().getUserRole(userId);
1403: }
1404:
1405: public Set getUsers() {
1406: return getAzg().getUsers();
1407: }
1408:
1409: public Set getUsersHasRole(String role) {
1410: return getAzg().getUsersHasRole(role);
1411: }
1412:
1413: public Set getUsersIsAllowed(String function) {
1414: return getAzg().getUsersIsAllowed(function);
1415: }
1416:
1417: public boolean hasRole(String userId, String role) {
1418: return getAzg().hasRole(userId, role);
1419: }
1420:
1421: public boolean isAllowed(String userId, String function) {
1422: return getAzg().isAllowed(userId, function);
1423: }
1424:
1425: public boolean isEmpty() {
1426: return getAzg().isEmpty();
1427: }
1428:
1429: public void removeMember(String userId) {
1430: m_azgChanged = true;
1431: getAzg().removeMember(userId);
1432: }
1433:
1434: public void removeMembers() {
1435: m_azgChanged = true;
1436: getAzg().removeMembers();
1437: }
1438:
1439: public void removeRole(String role) {
1440: m_azgChanged = true;
1441: getAzg().removeRole(role);
1442: }
1443:
1444: public void removeRoles() {
1445: m_azgChanged = true;
1446: getAzg().removeRoles();
1447: }
1448:
1449: public void setMaintainRole(String role) {
1450: m_azgChanged = true;
1451: getAzg().setMaintainRole(role);
1452: }
1453:
1454: public void setProviderGroupId(String id) {
1455: m_azgChanged = true;
1456: getAzg().setProviderGroupId(id);
1457: }
1458:
1459: public boolean keepIntersection(AuthzGroup other) {
1460: boolean changed = getAzg().keepIntersection(other);
1461: if (changed)
1462: m_azgChanged = true;
1463: return changed;
1464: }
1465: }
|