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, 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.ade.sitemap.shared; 029 030import org.opencms.ade.detailpage.CmsDetailPageInfo; 031import org.opencms.util.CmsUUID; 032 033import java.io.Serializable; 034import java.util.ArrayList; 035import java.util.Collection; 036import java.util.HashMap; 037import java.util.List; 038import java.util.Map; 039 040import com.google.common.collect.ArrayListMultimap; 041 042/** 043 * A data structure for managing the detail page ordering for different types in a given sitemap.<p> 044 * 045 * @since 8.0.0 046 */ 047public class CmsDetailPageTable implements Cloneable, Serializable { 048 049 /** A type indicating the status of a page. */ 050 public static enum Status { 051 /** default detail page. */ 052 firstDetailPage, /** no detail page. */ 053 noDetailPage, /** non-default detail page. */ 054 otherDetailPage 055 } 056 057 /** ID for serialization. */ 058 private static final long serialVersionUID = -4561142050519767250L; 059 060 /** The detail page info beans indexed by id. */ 061 private Map<CmsUUID, CmsDetailPageInfo> m_infoById = new HashMap<CmsUUID, CmsDetailPageInfo>(); 062 063 /** The detail page info beans, indexed by type. */ 064 private ArrayListMultimap<String, CmsDetailPageInfo> m_map = ArrayListMultimap.create(); 065 066 /** 067 * Creates a detail page table from a list of detail page info bean.<p> 068 * 069 * @param infos the detail page info beans 070 */ 071 public CmsDetailPageTable(List<CmsDetailPageInfo> infos) { 072 073 for (CmsDetailPageInfo info : infos) { 074 m_map.put(info.getType(), info); 075 m_infoById.put(info.getId(), info); 076 } 077 } 078 079 /** 080 * Empty default constructor for serialization.<p> 081 */ 082 protected CmsDetailPageTable() { 083 084 // for serialization 085 } 086 087 /** 088 * Adds a new detail page information bean to the detail page table.<p> 089 * 090 * @param info the detail page info to add 091 */ 092 public void add(CmsDetailPageInfo info) { 093 094 m_map.put(info.getType(), info); 095 m_infoById.put(info.getId(), info); 096 } 097 098 /** 099 * Moves the detail page information for a given page to the front of the detail pages for the same type.<p> 100 * 101 * @param id a page id 102 * 103 * @return the original position of the detail page entry in the list for the same type 104 */ 105 public int bump(CmsUUID id) { 106 107 CmsDetailPageInfo info = m_infoById.get(id); 108 if (info == null) { 109 throw new IllegalArgumentException(); 110 } 111 String type = info.getType(); 112 List<CmsDetailPageInfo> infos = m_map.get(type); 113 int oldPos = infos.indexOf(info); 114 infos.remove(oldPos); 115 infos.add(0, info); 116 return oldPos; 117 } 118 119 /** 120 * Returns true if the detail page table contains a page with a given id.<p> 121 * 122 * @param id the page id 123 * @return true if the detail page table contains the page with the given id 124 */ 125 public boolean contains(CmsUUID id) { 126 127 return m_infoById.containsKey(id); 128 } 129 130 /** 131 * Copies the detail page table.<p> 132 * 133 * @return the copy of the detail page table 134 */ 135 public CmsDetailPageTable copy() { 136 137 List<CmsDetailPageInfo> infos = toList(); 138 CmsDetailPageTable result = new CmsDetailPageTable(); 139 for (CmsDetailPageInfo info : infos) { 140 result.add(info); 141 } 142 return result; 143 } 144 145 /** 146 * Returns the detail page info for a given page id.<p> 147 * 148 * @param id a page id 149 * @return the detail page info for the given page id 150 */ 151 public CmsDetailPageInfo get(CmsUUID id) { 152 153 return m_infoById.get(id); 154 } 155 156 /** 157 * Returns the page ids of all detail pages. <p> 158 * 159 * @return the page ids of all detail pages 160 */ 161 public Collection<CmsUUID> getAllIds() { 162 163 return m_infoById.keySet(); 164 } 165 166 /** 167 * Returns the detail page which is in front of the detail page list for the given type.<p> 168 * 169 * @param type a resource type 170 * @return a detail page information bean 171 */ 172 public CmsDetailPageInfo getBestDetailPage(String type) { 173 174 List<CmsDetailPageInfo> infos = m_map.get(type); 175 if ((infos == null) || infos.isEmpty()) { 176 return null; 177 } 178 return infos.get(0); 179 } 180 181 /** 182 * Returns a list which contains the best detail page for each type.<p> 183 * 184 * @return the list of best detail pages for each type 185 */ 186 public List<CmsDetailPageInfo> getBestDetailPages() { 187 188 List<CmsDetailPageInfo> result = new ArrayList<CmsDetailPageInfo>(); 189 for (String key : m_map.keySet()) { 190 List<CmsDetailPageInfo> vals = m_map.get(key); 191 if (!vals.isEmpty()) { 192 result.add(vals.get(0)); 193 } 194 } 195 return result; 196 197 } 198 199 /** 200 * Returns the list of detail page info beans for a given type.<p> 201 * 202 * @param type the type for which the detail page beans should be retrieved 203 * 204 * @return the detail page beans for that type 205 */ 206 public List<CmsDetailPageInfo> getInfosForType(String type) { 207 208 return new ArrayList<CmsDetailPageInfo>(m_map.get(type)); 209 } 210 211 /** 212 * Returns the page status for the page with the given id.<p> 213 * 214 * @param id the id for which the page status should be checked 215 * 216 * @return the status of the page with the given id 217 */ 218 public Status getStatus(CmsUUID id) { 219 220 CmsDetailPageInfo info = m_infoById.get(id); 221 if (info == null) { 222 return Status.noDetailPage; 223 } 224 String type = info.getType(); 225 int index = m_map.get(type).indexOf(info); 226 if (index == 0) { 227 return Status.firstDetailPage; 228 } 229 return Status.otherDetailPage; 230 } 231 232 /** 233 * Returns true if the page with the given id is the default detail page for its type.<p> 234 * 235 * @param id a page id 236 * 237 * @return true if the detail page for the page id is the default detail page 238 */ 239 public boolean isDefaultDetailPage(CmsUUID id) { 240 241 CmsDetailPageInfo info = m_infoById.get(id); 242 if (info == null) { 243 return false; 244 } 245 return m_map.get(info.getType()).get(0).getId().equals(id); 246 } 247 248 /** 249 * Changes the position of a detail page in the list of detail pages for its type.<p> 250 * 251 * @param id the page id 252 * @param newPos the position which the page should be moved to 253 * 254 * @return the original position of the detail page 255 */ 256 public int move(CmsUUID id, int newPos) { 257 258 CmsDetailPageInfo info = m_infoById.get(id); 259 if (info == null) { 260 throw new IllegalArgumentException(); 261 } 262 String type = info.getType(); 263 List<CmsDetailPageInfo> infos = m_map.get(type); 264 int oldPos = infos.indexOf(info); 265 infos.remove(oldPos); 266 infos.add(newPos, info); 267 return oldPos; 268 } 269 270 /** 271 * Removes the detail page with the given id.<p> 272 * 273 * @param id the id of the detail page to remove 274 * 275 * @return the original position of the detail page in the list for its type 276 */ 277 public int remove(CmsUUID id) { 278 279 CmsDetailPageInfo info = m_infoById.get(id); 280 if (info == null) { 281 throw new IllegalArgumentException(); 282 } 283 String type = info.getType(); 284 List<CmsDetailPageInfo> infos = m_map.get(type); 285 int pos = infos.indexOf(info); 286 infos.remove(pos); 287 m_infoById.remove(id); 288 return pos; 289 290 } 291 292 /** 293 * The number of configured detail pages.<p> 294 * 295 * @return the number of detail pages 296 */ 297 public int size() { 298 299 return m_infoById.size(); 300 } 301 302 /** 303 * Returns a flat list containing all detail pages for all types which preserves the order of detail pages from each type list.<p> 304 * 305 * @return a list of all detail page info beans 306 */ 307 public List<CmsDetailPageInfo> toList() { 308 309 List<CmsDetailPageInfo> result = new ArrayList<CmsDetailPageInfo>(); 310 for (String key : m_map.keySet()) { 311 for (CmsDetailPageInfo info : m_map.get(key)) { 312 result.add(info); 313 } 314 } 315 return result; 316 } 317 318}