001    /*
002     * Copyright 2007-2010 The Kuali Foundation
003     *
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.opensource.org/licenses/ecl2.php
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.rice.kns.web;
017    
018    import java.util.HashMap;
019    import java.util.HashSet;
020    import java.util.LinkedList;
021    import java.util.Map;
022    import java.util.Queue;
023    import java.util.Set;
024    
025    import org.kuali.rice.kns.service.KNSServiceLocator;
026    import org.kuali.rice.kns.service.KualiConfigurationService;
027    import org.kuali.rice.kns.util.Guid;
028    
029    /**
030     * A class which will hold a Map of editable properties, dropping editable properties when too many
031     * are filled in. 
032     * 
033     * @author Kuali Rice Team (rice.collab@kuali.org)
034     *
035     */
036    public class EditablePropertiesHistoryHolder implements java.io.Serializable {
037            private Map<String, Set<String>> editablePropertiesMap;
038            private Integer maxLength = null;
039            private Queue<String> historyOrder;
040            private static final String EDITABLE_PROPERTIES_HISTORY_SIZE_PROPERTY_NAME = "kns.editable.properties.history.size";
041            private transient KualiConfigurationService configurationService;
042            
043            /**
044             * Constructs the EditablePropertiesHistoryHolder
045             *
046             */
047            public EditablePropertiesHistoryHolder() {
048                    editablePropertiesMap = new HashMap<String, Set<String>>();
049                    historyOrder = new LinkedList<String>();
050            }
051            
052            /**
053             * @return the maximum length of the history that this will hold
054             */
055            public int getMaxHistoryLength() {
056                    if (maxLength == null) {
057                            final String historyLengthAsString = getConfigurationService().getPropertyString(EditablePropertiesHistoryHolder.EDITABLE_PROPERTIES_HISTORY_SIZE_PROPERTY_NAME);
058                            if (historyLengthAsString == null) {
059                                    maxLength = new Integer(20);
060                            } else {
061                                    try {
062                                            maxLength = new Integer(historyLengthAsString);
063                                    } catch (NumberFormatException nfe) {
064                                            throw new RuntimeException("Cannot convert property "+EditablePropertiesHistoryHolder.EDITABLE_PROPERTIES_HISTORY_SIZE_PROPERTY_NAME+" with value "+historyLengthAsString+" to integer", nfe);
065                                    }
066                            }
067                    }
068                    return maxLength.intValue();
069            }
070            
071            /**
072             * Adds a Set of editable property names to the history, keyed with the given guid String.  If the editable properties exceeds the buffer size,
073             * the earliest editable properties will be bumped
074             * @param editableProperties the Set of editable property names to save in the history
075             * @return a String to act as a key (or guid) to the editable properties
076             */
077            public String addEditablePropertiesToHistory(Set<String> editableProperties) {
078                    String guid = generateNewGuid();
079                    
080                    if (getHistoryOrder().size() > getMaxHistoryLength()) {
081                            final String guidForRemoval = getHistoryOrder().remove();
082                            getEditablePropertiesMap().remove(guidForRemoval);
083                    }
084                    getHistoryOrder().add(guid);
085                    getEditablePropertiesMap().put(guid, editableProperties);
086                    
087                    return guid;
088            }
089            
090            /**
091             * 
092             * @return a newly generated Guid to act as a key to an editable properties Set
093             */
094            public String generateNewGuid() {
095                    final String guid = new Guid().toString();
096                    return guid;
097            }
098            
099            /**
100             * Returns the editable properties registered with the current guid
101             * @param guid the guid to find editable properties for
102             * @return a Set<String> of editable properties
103             */
104            public Set<String> getEditableProperties(String guid) {
105                    return getEditablePropertiesMap().get(guid);
106            }
107            
108            /**
109             * Clears out the editable properties associated with the given guid
110             * @param guid the guid to clear out editable properties for
111             */
112            public void clearEditableProperties(String guid) {
113                    getEditablePropertiesMap().put(guid, createNewEditablePropertiesEntry());
114            }
115            
116            /**
117             * @return the order of the entries as they chronologically were created
118             */
119            protected Queue<String> getHistoryOrder() {
120                    return historyOrder;
121            }
122            
123            /**
124             * @return the Map which associates editable property guids with Sets of editable property names
125             */
126            protected Map<String, Set<String>> getEditablePropertiesMap() {
127                    return editablePropertiesMap;
128            }
129            
130            /**
131             * @return a new Entry to hold the names of editable properties
132             */
133            protected Set<String> createNewEditablePropertiesEntry() {
134                    return new HashSet<String>();
135            }
136            
137            /**
138             * @return an implementation of the KualiConfigurationService
139             */
140            protected KualiConfigurationService getConfigurationService() {
141                    if (configurationService == null) {
142                            configurationService = KNSServiceLocator.getKualiConfigurationService();
143                    }
144                    return configurationService;
145            }
146    }