001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software GmbH & Co. KG, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.relations; 029 030import org.opencms.file.CmsObject; 031import org.opencms.file.CmsResource; 032import org.opencms.file.CmsResourceFilter; 033import org.opencms.file.CmsVfsResourceNotFoundException; 034import org.opencms.main.CmsException; 035import org.opencms.util.CmsUUID; 036 037import java.util.Comparator; 038 039/** 040 * A relation between two opencms resources.<p> 041 * 042 * @since 6.3.0 043 */ 044public class CmsRelation { 045 046 /** 047 * A comparator for the source & target path plus the relation type of 2 relations.<p> 048 */ 049 public static final Comparator<CmsRelation> COMPARATOR = new Comparator<CmsRelation>() { 050 051 /** 052 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) 053 */ 054 public int compare(CmsRelation r1, CmsRelation r2) { 055 056 if (r1 == r2) { 057 return 0; 058 } 059 String p1 = r1.getSourcePath() + r1.getTargetPath() + r1.getType().getId(); 060 String p2 = r2.getSourcePath() + r2.getTargetPath() + r2.getType().getId(); 061 062 return p1.compareTo(p2); 063 } 064 }; 065 066 /** Default value for undefined Strings. */ 067 private static final String UNDEF = ""; 068 069 /** Cached hash code. */ 070 private int m_hashCode; 071 072 /** The structure id of the source resource. */ 073 private final CmsUUID m_sourceId; 074 075 /** The path of the source resource. */ 076 private final String m_sourcePath; 077 078 /** The structure id of the target resource. */ 079 private final CmsUUID m_targetId; 080 081 /** The path of the target resource. */ 082 private final String m_targetPath; 083 084 /** The relation type. */ 085 private final CmsRelationType m_type; 086 087 /** 088 * Creates a new relation object of the given type between the given resources.<p> 089 * 090 * @param source the source resource 091 * @param target the target resource 092 * @param type the relation type 093 */ 094 public CmsRelation(CmsResource source, CmsResource target, CmsRelationType type) { 095 096 this(source.getStructureId(), source.getRootPath(), target.getStructureId(), target.getRootPath(), type); 097 } 098 099 /** 100 * Base constructor.<p> 101 * 102 * @param sourceId the source structure id 103 * @param sourcePath the source path 104 * @param targetId the target structure id 105 * @param targetPath the target path 106 * @param type the relation type 107 */ 108 public CmsRelation(CmsUUID sourceId, String sourcePath, CmsUUID targetId, String targetPath, CmsRelationType type) { 109 110 // make sure no value can ever be null 111 m_sourceId = ((sourceId != null) ? sourceId : CmsUUID.getNullUUID()); 112 m_sourcePath = ((sourcePath != null) ? sourcePath : UNDEF); 113 m_targetId = ((targetId != null) ? targetId : CmsUUID.getNullUUID()); 114 m_targetPath = ((targetPath != null) ? targetPath : UNDEF); 115 m_type = ((type != null) ? type : CmsRelationType.XML_WEAK); 116 } 117 118 /** 119 * @see java.lang.Object#equals(java.lang.Object) 120 */ 121 @Override 122 public boolean equals(Object obj) { 123 124 if (this == obj) { 125 return true; 126 } 127 if (obj instanceof CmsRelation) { 128 CmsRelation other = (CmsRelation)obj; 129 return (m_type == other.m_type) 130 // && (m_dateBegin == other.m_dateBegin) 131 // && (m_dateEnd == other.m_dateEnd) 132 && (m_sourcePath.equals(other.m_sourcePath) || m_sourceId.equals(other.m_sourceId)) 133 && (m_targetPath.equals(other.m_targetPath) || m_targetId.equals(other.m_targetId)); 134 } 135 return false; 136 } 137 138 /** 139 * Returns the source resource when possible to read with the given filter.<p> 140 * 141 * @param cms the current user context 142 * @param filter the filter to use 143 * 144 * @return the source resource 145 * 146 * @throws CmsException if something goes wrong 147 */ 148 public CmsResource getSource(CmsObject cms, CmsResourceFilter filter) throws CmsException { 149 150 try { 151 // first look up by id 152 return cms.readResource(getSourceId(), filter); 153 } catch (CmsVfsResourceNotFoundException e) { 154 // then look up by name, but from the root site 155 String storedSiteRoot = cms.getRequestContext().getSiteRoot(); 156 try { 157 cms.getRequestContext().setSiteRoot(""); 158 return cms.readResource(getSourcePath(), filter); 159 } finally { 160 cms.getRequestContext().setSiteRoot(storedSiteRoot); 161 } 162 } 163 } 164 165 /** 166 * Returns the structure id of the source resource.<p> 167 * 168 * @return the structure id of the source resource 169 */ 170 public CmsUUID getSourceId() { 171 172 return m_sourceId; 173 } 174 175 /** 176 * Returns the path of the source resource.<p> 177 * 178 * @return the path of the source resource 179 */ 180 public String getSourcePath() { 181 182 return m_sourcePath; 183 } 184 185 /** 186 * Returns the target resource when possible to read with the given filter.<p> 187 * 188 * @param cms the current user context 189 * @param filter the filter to use 190 * 191 * @return the target resource 192 * 193 * @throws CmsException if something goes wrong 194 */ 195 public CmsResource getTarget(CmsObject cms, CmsResourceFilter filter) throws CmsException { 196 197 try { 198 // first look up by id 199 return cms.readResource(getTargetId(), filter); 200 } catch (CmsVfsResourceNotFoundException e) { 201 // then look up by name, but from the root site 202 String storedSiteRoot = cms.getRequestContext().getSiteRoot(); 203 try { 204 cms.getRequestContext().setSiteRoot(""); 205 return cms.readResource(getTargetPath(), filter); 206 } finally { 207 cms.getRequestContext().setSiteRoot(storedSiteRoot); 208 } 209 } 210 } 211 212 /** 213 * Returns the structure id of the target resource.<p> 214 * 215 * @return the structure id of the target resource 216 */ 217 public CmsUUID getTargetId() { 218 219 return m_targetId; 220 } 221 222 /** 223 * Returns the path of the target resource.<p> 224 * 225 * @return the path of the target resource 226 */ 227 public String getTargetPath() { 228 229 return m_targetPath; 230 } 231 232 /** 233 * Returns the relation type.<p> 234 * 235 * @return the relation type 236 */ 237 public CmsRelationType getType() { 238 239 return m_type; 240 } 241 242 /** 243 * @see java.lang.Object#hashCode() 244 */ 245 @Override 246 public int hashCode() { 247 248 if (m_hashCode == 0) { 249 // calculate hash code only once 250 final int PRIME = 31; 251 int result = 1; 252 result = (PRIME * result) + ((m_sourceId == null) ? 0 : m_sourceId.hashCode()); 253 result = (PRIME * result) + ((m_sourcePath == null) ? 0 : m_sourcePath.hashCode()); 254 result = (PRIME * result) + ((m_targetId == null) ? 0 : m_targetId.hashCode()); 255 result = (PRIME * result) + ((m_targetPath == null) ? 0 : m_targetPath.hashCode()); 256 result = (PRIME * result) + ((m_type == null) ? 0 : m_type.hashCode()); 257 m_hashCode = result; 258 } 259 return m_hashCode; 260 } 261 262 /** 263 * @see java.lang.Object#toString() 264 */ 265 @Override 266 public String toString() { 267 268 StringBuffer str = new StringBuffer(); 269 str.append("CmsRelation ["); 270 str.append("source id: ").append(m_sourceId).append(", "); 271 str.append("source path: ").append(m_sourcePath).append(", "); 272 str.append("target id: ").append(m_targetId).append(", "); 273 str.append("target path: ").append(m_targetPath).append(", "); 274 str.append("type: ").append(m_type); 275 str.append("]"); 276 return str.toString(); 277 } 278}