001/** 002 * Copyright 2010-2013 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 */ 016package org.kuali.common.util.property; 017 018import java.io.InputStream; 019import java.io.Reader; 020import java.util.Collection; 021import java.util.Collections; 022import java.util.Map; 023import java.util.Properties; 024import java.util.Set; 025 026import org.kuali.common.util.Assert; 027 028public final class ImmutableProperties extends Properties { 029 030 private static final long serialVersionUID = -3964884087103719367L; 031 private static final String UOE_MSG = "Immutable properties cannot be changed"; 032 private static final Properties EMPTY = ImmutableProperties.of(new Properties()); 033 034 public ImmutableProperties(Properties original) { 035 Assert.noNulls(original); 036 037 // Prevent anything from changing original until we are done 038 synchronized (original) { 039 040 // Extract only those keys where both the key and its corresponding value are strings 041 Set<String> keys = original.stringPropertyNames(); 042 043 // If the sizes are different, original contains at least one key or value that is not a string 044 Assert.isTrue(keys.size() == original.size(), "Immutable properties only support strings"); 045 046 // Copy every key/value pair from original - can't use putAll() since it calls put() which is now disabled 047 for (String key : keys) { 048 super.put(key, original.getProperty(key)); 049 } 050 } 051 } 052 053 public static Properties of() { 054 return EMPTY; 055 } 056 057 /** 058 * Create and return a new immutable properties object identical to the one passed in. If <code>properties</code> is already immutable, no new object is created, the 059 * <code>properties</code> object passed in as a method argument is what is returned. 060 * 061 * @throws NullPointerException 062 * if {@code properties} is null 063 * 064 * @deprecated use copyOf(Properties) instead 065 */ 066 @Deprecated 067 public static Properties of(Properties properties) { 068 if (properties instanceof ImmutableProperties) { 069 return properties; 070 } else { 071 return new ImmutableProperties(properties); 072 } 073 } 074 075 /** 076 * Create and return a new immutable properties object identical to the one passed in. If <code>properties</code> is already immutable, no new object is created, the 077 * <code>properties</code> object passed in as a method argument is what is returned. 078 * 079 * @throws NullPointerException 080 * if {@code properties} is null 081 */ 082 public static ImmutableProperties copyOf(Properties properties) { 083 if (properties instanceof ImmutableProperties) { 084 return (ImmutableProperties) properties; 085 } else { 086 return new ImmutableProperties(properties); 087 } 088 } 089 090 @Override 091 public Object setProperty(String key, String value) { 092 throw new UnsupportedOperationException(UOE_MSG); 093 } 094 095 @Override 096 public void load(Reader reader) { 097 throw new UnsupportedOperationException(UOE_MSG); 098 } 099 100 @Override 101 public void load(InputStream inStream) { 102 throw new UnsupportedOperationException(UOE_MSG); 103 } 104 105 @Override 106 public void loadFromXML(InputStream in) { 107 throw new UnsupportedOperationException(UOE_MSG); 108 } 109 110 @Override 111 public Object put(Object key, Object value) { 112 throw new UnsupportedOperationException(UOE_MSG); 113 } 114 115 @Override 116 public Object remove(Object key) { 117 throw new UnsupportedOperationException(UOE_MSG); 118 } 119 120 @Override 121 public void putAll(Map<? extends Object, ? extends Object> t) { 122 throw new UnsupportedOperationException(UOE_MSG); 123 } 124 125 @Override 126 public void clear() { 127 throw new UnsupportedOperationException(UOE_MSG); 128 } 129 130 @Override 131 public Set<Object> keySet() { 132 return Collections.unmodifiableSet(super.keySet()); 133 } 134 135 @Override 136 public Set<java.util.Map.Entry<Object, Object>> entrySet() { 137 return Collections.unmodifiableSet(super.entrySet()); 138 } 139 140 @Override 141 public Collection<Object> values() { 142 return Collections.unmodifiableCollection(super.values()); 143 } 144 145}