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.contenteditor.client; 029 030import org.opencms.acacia.shared.CmsEntity; 031import org.opencms.ade.contenteditor.shared.CmsContentDefinition; 032import org.opencms.gwt.client.util.CmsClientStringUtil; 033import org.opencms.gwt.client.util.CmsDebugLog; 034 035import java.util.ArrayList; 036import java.util.HashMap; 037import java.util.List; 038import java.util.Map; 039 040import com.google.gwt.event.logical.shared.ValueChangeEvent; 041import com.google.gwt.event.logical.shared.ValueChangeHandler; 042import com.google.gwt.event.shared.HandlerRegistration; 043 044/** 045 * Observer for content entities, used to notify listeners of entity changes.<p> 046 */ 047public class CmsEntityObserver implements ValueChangeHandler<CmsEntity> { 048 049 /** The registered change listeners. */ 050 Map<String, List<I_CmsEntityChangeListener>> m_changeListeners; 051 052 /** The scope values. */ 053 Map<String, String> m_scopeValues; 054 055 /** The change handler registration. */ 056 private HandlerRegistration m_handlerRegistration; 057 058 /** The observed entity. */ 059 private CmsEntity m_observerdEntity; 060 061 /** 062 * Constructor.<p> 063 * 064 * @param entity the entity to observe 065 */ 066 public CmsEntityObserver(CmsEntity entity) { 067 068 m_observerdEntity = entity; 069 m_handlerRegistration = entity.addValueChangeHandler(this); 070 m_changeListeners = new HashMap<String, List<I_CmsEntityChangeListener>>(); 071 m_scopeValues = new HashMap<String, String>(); 072 } 073 074 /** 075 * Adds an entity change listener for the given scope.<p> 076 * 077 * @param changeListener the change listener 078 * @param changeScope the change scope 079 */ 080 public void addEntityChangeListener(I_CmsEntityChangeListener changeListener, String changeScope) { 081 082 if (m_observerdEntity == null) { 083 throw new RuntimeException("The Observer has been cleared, no listener registration possible."); 084 } 085 if (!m_changeListeners.containsKey(changeScope)) { 086 m_changeListeners.put(changeScope, new ArrayList<I_CmsEntityChangeListener>()); 087 // if changeScope==null, it is a global change listener, and we don't need a scope value 088 if (changeScope != null) { 089 // save the current change scope value 090 m_scopeValues.put(changeScope, CmsContentDefinition.getValueForPath(m_observerdEntity, changeScope)); 091 } 092 } 093 m_changeListeners.get(changeScope).add(changeListener); 094 } 095 096 /** 097 * Removes this observer from the entities change handler registration and clears registered listeners.<p> 098 */ 099 public void clear() { 100 101 if (m_handlerRegistration != null) { 102 m_handlerRegistration.removeHandler(); 103 m_handlerRegistration = null; 104 } 105 m_changeListeners.clear(); 106 m_scopeValues.clear(); 107 m_observerdEntity = null; 108 } 109 110 /** 111 * @see com.google.gwt.event.logical.shared.ValueChangeHandler#onValueChange(com.google.gwt.event.logical.shared.ValueChangeEvent) 112 */ 113 public void onValueChange(ValueChangeEvent<CmsEntity> event) { 114 115 CmsEntity entity = event.getValue(); 116 if (m_changeListeners.containsKey(null)) { 117 for (I_CmsEntityChangeListener listener : m_changeListeners.get(null)) { 118 safeExecuteChangeListener(entity, listener); 119 } 120 } 121 for (String scope : m_scopeValues.keySet()) { 122 System.out.println("checking scope " + scope + " on change"); 123 String scopeValue = CmsContentDefinition.getValueForPath(entity, scope); 124 String previousValue = m_scopeValues.get(scope); 125 if (((scopeValue != null) && !scopeValue.equals(previousValue)) 126 || ((scopeValue == null) && (previousValue != null))) { 127 m_scopeValues.put(scope, scopeValue); 128 // the value within this scope has changed, notify all listeners 129 if (m_changeListeners.containsKey(scope)) { 130 System.out.println("calling listeners on changed scope " + scope); 131 for (I_CmsEntityChangeListener changeListener : m_changeListeners.get(scope)) { 132 safeExecuteChangeListener(entity, changeListener); 133 } 134 } 135 } 136 } 137 } 138 139 /** 140 * Calls an entity change listener, catching any errors.<p> 141 * 142 * @param entity the entity with which the change listener should be called 143 * @param listener the change listener 144 */ 145 protected void safeExecuteChangeListener(CmsEntity entity, I_CmsEntityChangeListener listener) { 146 147 try { 148 listener.onEntityChange(entity); 149 } catch (Exception e) { 150 String stack = CmsClientStringUtil.getStackTrace(e, "<br />"); 151 CmsDebugLog.getInstance().printLine("<br />" + e.getMessage() + "<br />" + stack); 152 } 153 } 154}