001 /* 002 * Copyright 2002-2004 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 005 * use this file except in compliance with the License. You may obtain a copy of 006 * the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 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, WITHOUT 012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 013 * License for the specific language governing permissions and limitations under 014 * the License. 015 */ 016 package org.springframework.richclient.settings.xml; 017 018 import java.io.IOException; 019 import java.util.ArrayList; 020 import java.util.HashMap; 021 import java.util.List; 022 import java.util.Map; 023 024 import org.springframework.richclient.settings.AbstractSettings; 025 import org.springframework.richclient.settings.Settings; 026 import org.springframework.util.Assert; 027 import org.w3c.dom.Element; 028 import org.w3c.dom.Node; 029 import org.w3c.dom.NodeList; 030 031 /** 032 * @author Peter De Bruycker 033 */ 034 public class XmlSettings extends AbstractSettings { 035 private Element element; 036 037 private boolean entriesLoaded; 038 039 private Map values = new HashMap(); 040 041 public XmlSettings(Settings parent, Element element) { 042 super(parent, getName(element)); 043 this.element = element; 044 } 045 046 public XmlSettings(Element element) { 047 this(null, element); 048 } 049 050 private static String getName(Element element) { 051 verifyElement(element); 052 053 return element.getAttribute("name"); 054 } 055 056 private static void verifyElement(Element element) { 057 Assert.notNull(element, "element cannot be null"); 058 Assert.isTrue(element.getNodeName().equals("settings"), "element must be settings"); 059 Assert.isTrue(element.hasAttribute("name"), "element must have name attribute"); 060 } 061 062 protected Settings internalCreateChild(String key) { 063 loadChildrenIfNecessary(); 064 065 Element childElement = null; 066 067 NodeList childNodes = element.getChildNodes(); 068 for (int i = 0; i < childNodes.getLength(); i++) { 069 Node node = childNodes.item(i); 070 if (node instanceof Element) { 071 Element tmp = (Element) node; 072 if (tmp.getNodeName().equals("settings") && tmp.getAttribute("name").equals(key)) { 073 childElement = tmp; 074 } 075 } 076 } 077 078 if (childElement == null) { 079 childElement = element.getOwnerDocument().createElement("settings"); 080 childElement.setAttribute("name", key); 081 element.appendChild(childElement); 082 } 083 084 return new XmlSettings(this, childElement); 085 } 086 087 protected boolean internalContains(String key) { 088 loadChildrenIfNecessary(); 089 090 return values.containsKey(key); 091 } 092 093 protected void internalSet(String key, String value) { 094 loadChildrenIfNecessary(); 095 096 Element entry = findOrCreateEntry(key); 097 entry.setAttribute("value", value); 098 099 values.put(key, value); 100 } 101 102 private Element findEntry(String key) { 103 NodeList childNodes = element.getChildNodes(); 104 for (int i = 0; i < childNodes.getLength(); i++) { 105 Node node = childNodes.item(i); 106 if (node instanceof Element && node.getNodeName().equals("entry")) { 107 Element tmp = (Element) node; 108 if (tmp.getAttribute("key").equals(key)) { 109 return tmp; 110 } 111 } 112 } 113 114 return null; 115 } 116 117 private Element findOrCreateEntry(String key) { 118 Element entry = findEntry(key); 119 if (entry == null) { 120 entry = element.getOwnerDocument().createElement("entry"); 121 entry.setAttribute("key", key); 122 element.appendChild(entry); 123 } 124 125 return entry; 126 } 127 128 protected String internalGet(String key) { 129 loadChildrenIfNecessary(); 130 131 return (String) values.get(key); 132 } 133 134 public String[] getKeys() { 135 loadChildrenIfNecessary(); 136 137 return (String[]) values.keySet().toArray(new String[values.size()]); 138 } 139 140 public void save() throws IOException { 141 getParent().save(); 142 } 143 144 private void loadChildrenIfNecessary() { 145 if (!entriesLoaded) { 146 NodeList childNodes = element.getChildNodes(); 147 for (int i = 0; i < childNodes.getLength(); i++) { 148 Node node = childNodes.item(i); 149 if (node instanceof Element) { 150 Element el = (Element) node; 151 if (el.getNodeName().equals("entry")) { 152 // entry 153 values.put(el.getAttribute("key"), el.getAttribute("value")); 154 } 155 } 156 } 157 158 entriesLoaded = true; 159 } 160 } 161 162 public void load() throws IOException { 163 loadChildrenIfNecessary(); 164 } 165 166 protected void internalRemove(String key) { 167 loadChildrenIfNecessary(); 168 169 Element entry = findEntry(key); 170 if (entry != null) { 171 element.removeChild(entry); 172 } 173 174 values.remove(key); 175 } 176 177 public Element getElement() { 178 return element; 179 } 180 181 protected String[] internalGetChildSettings() { 182 List childSettingsNames = new ArrayList(); 183 184 NodeList childNodes = element.getChildNodes(); 185 for (int i = 0; i < childNodes.getLength(); i++) { 186 Node node = childNodes.item(i); 187 if (node instanceof Element) { 188 Element el = (Element) node; 189 if (el.getNodeName().equals("settings")) { 190 childSettingsNames.add(el.getAttribute("name")); 191 } 192 } 193 } 194 195 return (String[]) childSettingsNames.toArray(new String[childSettingsNames.size()]); 196 } 197 198 public void internalRemoveSettings() { 199 element.getParentNode().removeChild(element); 200 } 201 }