Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *    Purpose:  A Class that implements skins configuration methods
4
 *  Copyright: 2008 Regents of the University of California and the
5
 *             National Center for Ecological Analysis and Synthesis
6
 *    Authors: Michael Daigle
7
 *
8
 *   '$Author: daigle $'
9
 *     '$Date: 2009-10-06 10:55:18 -0700 (Tue, 06 Oct 2009) $'
10
 * '$Revision: 5076 $'
11
 *
12
 * This program is free software; you can redistribute it and/or modify
13
 * it under the terms of the GNU General Public License as published by
14
 * the Free Software Foundation; either version 2 of the License, or
15
 * (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU General Public License
23
 * along with this program; if not, write to the Free Software
24
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25
 */
26

    
27
package edu.ucsb.nceas.metacat.admin;
28

    
29
import java.io.IOException;
30
import java.util.HashMap;
31
import java.util.Set;
32
import java.util.Vector;
33

    
34
import javax.servlet.http.HttpServletRequest;
35
import javax.servlet.http.HttpServletResponse;
36

    
37
import org.apache.log4j.Logger;
38

    
39
import edu.ucsb.nceas.metacat.properties.PropertyService;
40
import edu.ucsb.nceas.metacat.properties.SkinPropertyService;
41
import edu.ucsb.nceas.metacat.shared.MetacatUtilException;
42
import edu.ucsb.nceas.metacat.util.RequestUtil;
43
import edu.ucsb.nceas.metacat.util.SkinUtil;
44
import edu.ucsb.nceas.utilities.MetaDataProperty;
45
import edu.ucsb.nceas.utilities.PropertiesMetaData;
46
import edu.ucsb.nceas.utilities.GeneralPropertyException;
47
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
48
import edu.ucsb.nceas.utilities.SortedProperties;
49

    
50
/**
51
 * Control the display of the skins configuration page and the processing
52
 * of the configuration values.
53
 */
54
public class SkinsAdmin extends MetacatAdmin {
55

    
56
	private static SkinsAdmin skinsAdmin = null;
57
	private static Logger logMetacat = Logger.getLogger(SkinsAdmin.class);
58

    
59
	/**
60
	 * private constructor since this is a singleton
61
	 */
62
	private SkinsAdmin() {}
63

    
64
	/**
65
	 * Get the single instance of the MetaCatConfig.
66
	 * 
67
	 * @return the single instance of MetaCatConfig
68
	 */
69
	public static SkinsAdmin getInstance() {
70
		if (skinsAdmin == null) {
71
			skinsAdmin = new SkinsAdmin();
72
		}
73
		return skinsAdmin;
74
	}
75
	
76
	/**
77
	 * Handle configuration of the application the first time that Metacat
78
	 * starts or when it is explicitly called in the url. Collect necessary
79
	 * configuration information from the administrator.
80
	 * 
81
	 * @param request
82
	 *            the http request information
83
	 * @param response
84
	 *            the http response to be sent back to the client
85
	 */
86
	public void configureSkins(HttpServletRequest request, HttpServletResponse response)
87
			throws AdminException {
88

    
89
		String processForm = request.getParameter("processForm");
90
		String formErrors = (String) request.getAttribute("formErrors");
91

    
92
		if (processForm == null || !processForm.equals("true") || formErrors != null) {
93
			// The servlet configuration parameters have not been set, or there
94
			// were form errors on the last attempt to configure, so redirect to
95
			// the web form for configuring metacat
96
			try {
97
				Vector<String> skinNames = SkinUtil.getSkinNames();
98
				String defaultStyle = 
99
					PropertyService.getProperty("application.default-style");
100

    
101
				request.setAttribute("defaultStyle", defaultStyle);
102
				
103
				// add skin metadata to the request.  The configuration form
104
				// will use this data to determine what the configuration 
105
				// fields should look like.
106
				HashMap<String, PropertiesMetaData> propertyMetaData = 
107
					SkinPropertyService.getMetaData();
108
				request.setAttribute("metadataMap", propertyMetaData);
109
				
110
				// get a deep copy of properties so we can override with 
111
				// backup values without changing originals
112
				HashMap<String, SortedProperties> originalPropertyMap =
113
					SkinPropertyService.getProperties();
114
				HashMap<String, HashMap<String, String>> localPropertyMap =
115
					new HashMap<String, HashMap<String, String>>();
116
				HashMap<String, SortedProperties> backupPropertiesMap = 
117
					SkinPropertyService.getBackupProperties();
118
				
119
				// Just in case a skin is not configured correctly, we will want to remove 
120
				// it from the skins list
121
				Vector<String> removeSkins = new Vector<String>();
122
					
123
				for (String skinName : skinNames) {
124
					// first, get a deep copy of this skin's properties
125

    
126
					SortedProperties skinProperties = originalPropertyMap.get(skinName);
127
					if (skinProperties == null) {
128
						logMetacat.error("SkinsAdmin.configureSkins - Could not find properties for skin: " + skinName);
129
						removeSkins.add(skinName);
130
						continue;
131
					}
132

    
133
					HashMap<String, String> originalSkinProperties = 
134
						skinProperties.getProperties();
135
					HashMap<String, String> localSkinProperties = 
136
						new HashMap<String, String>(originalSkinProperties);
137

    
138
					// now get the backup properties for this skin.  Overwrite the 
139
					// properties with backup properties.  This allows previously 
140
					// set properties to be preserved in an application upgrade.
141
					SortedProperties backupProperties = backupPropertiesMap.get(skinName);
142
					if (backupProperties == null) {
143
						logMetacat.warn("SkinsAdmin.configureSkins - Could not find backup properties for skin: "
144
								+ skinName);
145
					} else {
146
						for (String propertyName : backupProperties.getPropertyNames()) {
147
							localSkinProperties.put(propertyName, 
148
									backupProperties.getProperty(propertyName));
149
						}
150
					}
151
								
152
					localPropertyMap.put(skinName, localSkinProperties);					
153
				}	
154
				
155
				// If there are any skins for which we could not get properties, remove them from 
156
				// the skins list we will send to the configuration page.
157
				for (String skinName : removeSkins) {
158
					skinNames.remove(skinName);
159
				}
160
				
161
				request.setAttribute("skinNameList", skinNames);
162
				request.setAttribute("skinProperties", localPropertyMap);
163
				
164
				// Forward the request to the JSP page
165
				RequestUtil.forwardRequest(request, response,
166
						"/admin/skins-configuration.jsp", null);
167

    
168
			} catch (GeneralPropertyException pnfe) {
169
				throw new AdminException("SkinsAdmin.configureSkins - Problem getting property while " + 
170
						"initializing skins properties page: " + pnfe.getMessage());
171
			} catch (MetacatUtilException mue) {
172
				throw new AdminException("SkinsAdmin.configureSkins - utility problem while initializing "
173
						+ "skins properties page:" + mue.getMessage());
174
			} 
175

    
176
		} else {
177
			// The configuration form is being submitted and needs to be
178
			// processed.
179
			Vector<String> processingSuccess = new Vector<String>();
180
			Vector<String> processingErrors = new Vector<String>();
181
			Vector<String> validationErrors = new Vector<String>();
182

    
183
			try {
184
				//Default style is global.
185
				String defaultStyle = request.getParameter("application.default-style");
186
				PropertyService.setProperty("application.default-style", defaultStyle);
187
				
188
				// For each skin property, check if it is changed and save it
189
				Vector<String> skinNames = SkinUtil.getSkinNames();
190
				for (String skinName : skinNames) {
191
					PropertiesMetaData skinMetaData = 
192
						SkinPropertyService.getMetaData(skinName);
193
					
194
					if (skinMetaData == null) {
195
						logMetacat.error("SkinsAdmin.configureSkins - Could not find metadata for skin: " + skinName);
196
						continue;
197
					}
198
					
199
					Set<String> metaDataKeySet = skinMetaData.getKeys();
200
					for (String metaDataKey : metaDataKeySet) {
201
						MetaDataProperty metaDataProperty = 
202
							skinMetaData.getProperties().get(metaDataKey);
203
						String fieldType = metaDataProperty.getFieldType();
204
						String newValue = request.getParameter(skinName + "." + metaDataKey);
205
						if (fieldType != null && fieldType.equals(MetaDataProperty.CHECKBOX_TYPE)) {
206
							if (newValue != null && newValue.equals("on")) {
207
								SkinPropertyService.checkAndSetProperty("true", skinName, metaDataKey);
208
							} else {
209
								SkinPropertyService.checkAndSetProperty("false", skinName, metaDataKey);
210
							}								
211
						} else {		
212
							SkinPropertyService.checkAndSetProperty(request, skinName, metaDataKey);
213
						}
214
					}
215

    
216
					// we need to write the options from memory to the
217
					// properties file
218
					SkinPropertyService.persistProperties(skinName);
219

    
220
					// Validate that the options provided are legitimate. Note
221
					// that we've allowed them to persist their entries. As of 
222
					// this point there is no other easy way to go back to the 
223
					// configure form and preserve their entries.
224
					validationErrors.addAll(validateOptions(request, skinName));
225

    
226
					// write the backup properties to a location outside the
227
					// application directories so they will be available after
228
					// the next upgrade
229
					SkinPropertyService.persistBackupProperties(skinName);
230
					PropertyService.persistMainBackupProperties();
231
				}
232
				
233
				// Now that the options have been set, change the 'skinsConfigured'
234
				// option to 'true' so that normal metacat requests will go through
235
				PropertyService.setProperty("configutil.skinsConfigured",
236
						PropertyService.CONFIGURED);
237
			} catch (GeneralPropertyException gpe) {
238
				String errorMessage = "SkinsAdmin.configureSkins - problem setting property while processing skins "
239
						+ "properties page: " + gpe.getMessage();
240
				logMetacat.error(errorMessage);
241
				processingErrors.add(errorMessage);
242
			} catch (IOException ioe) {
243
				String errorMessage = "SkinsAdmin.configureSkins - IO problem while processing skins "
244
						+ "properties page: " + ioe.getMessage();
245
				logMetacat.error(errorMessage);
246
				processingErrors.add(errorMessage);
247
			}
248
			try {
249
				if (validationErrors.size() > 0 || processingErrors.size() > 0) {
250
					RequestUtil.clearRequestMessages(request);
251
					RequestUtil.setRequestFormErrors(request, validationErrors);
252
					RequestUtil.setRequestErrors(request, processingErrors);
253
					RequestUtil.forwardRequest(request, response, "/admin", null);
254
				} else {
255
					// Now that the options have been set, change the
256
					// 'skinsConfigured' option to 'true'
257
					PropertyService.setProperty("configutil.skinsConfigured",
258
							PropertyService.CONFIGURED);
259

    
260
					// Reload the main metacat configuration page
261
					processingSuccess.add("Skins successfully configured");
262
					RequestUtil.clearRequestMessages(request);
263
					RequestUtil.setRequestSuccess(request, processingSuccess);
264
					RequestUtil.forwardRequest(request, response,
265
							"/admin?configureType=configure&processForm=false", null);
266
				}
267
			} catch (MetacatUtilException mue) {
268
				throw new AdminException("SkinsAdmin.configureSkins - utility problem while processing skins "
269
						+ "properties page: " + mue.getMessage());
270
			} catch (GeneralPropertyException gpe) {
271
				String errorMessage = "SkinsAdmin.configureSkins - problem setting property while processing skins "
272
						+ "properties page: " + gpe.getMessage();
273
				logMetacat.error(errorMessage);
274
				processingErrors.add(errorMessage);
275
			}
276
		}
277
	}
278
	
279
	protected Vector<String> validateOptions(HttpServletRequest request) {
280
		Vector<String> errorVector = new Vector<String>();
281
		Vector<String> skinNames = null;
282
		try {
283
			skinNames = SkinUtil.getSkinNames();
284
		} catch (PropertyNotFoundException pnfe) {
285
			errorVector.add("Could not find skin names: " + pnfe.getMessage());
286
		}
287
		
288
		for (String skinName : skinNames) {
289
			errorVector.addAll(validateOptions(request, skinName));
290
		}
291
		
292
		return errorVector;
293
	}
294
	
295
	/**
296
	 * Validate the most important configuration options submitted by the user.
297
	 * 
298
	 * @return a vector holding error message for any fields that fail
299
	 *         validation.
300
	 */
301
	protected Vector<String> validateOptions(HttpServletRequest request, String skinName) {
302
		Vector<String> errorVector = new Vector<String>();
303

    
304
		//TODO MCD validate options.
305

    
306
		return errorVector;
307
	}
308
}
(12-12/12)