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: 2008-11-25 12:40:45 -0800 (Tue, 25 Nov 2008) $'
10
 * '$Revision: 4632 $'
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.ServletException;
35
import javax.servlet.http.HttpServletRequest;
36
import javax.servlet.http.HttpServletResponse;
37

    
38
import org.apache.log4j.Logger;
39

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

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

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

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

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

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

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

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

    
124
					SortedProperties skinProperties = originalPropertyMap.get(skinName);
125
					if (skinProperties == null) {
126
						throw new GeneralPropertyException("Could not find properties " 
127
								+ "for skin: " + skinName);
128
					}
129

    
130
					HashMap<String, String> originalSkinProperties = 
131
						skinProperties.getProperties();
132
					HashMap<String, String> localSkinProperties = 
133
						new HashMap<String, String>(originalSkinProperties);
134

    
135
					// now get the backup properties for this skin.  Overwrite the 
136
					// properties with backup properties.  This allows previously 
137
					// set properties to be preserved in an application upgrade.
138
					SortedProperties backupProperties = backupPropertiesMap.get(skinName);
139
					if (backupProperties == null) {
140
						logMetacat.warn("Could not find backup properties for skin: "
141
								+ skinName);
142
					} else {
143
						for (String propertyName : backupProperties.getPropertyNames()) {
144
							localSkinProperties.put(propertyName, 
145
									backupProperties.getProperty(propertyName));
146
						}
147
					}
148
								
149
					localPropertyMap.put(skinName, localSkinProperties);					
150
				}				
151
				request.setAttribute("skinProperties", localPropertyMap);
152
				
153
				// Forward the request to the JSP page
154
				RequestUtil.forwardRequest(request, response,
155
						"/admin/skins-configuration.jsp");
156

    
157
			} catch (GeneralPropertyException pnfe) {
158
				throw new AdminException("Problem getting property while initializing "
159
						+ "skins properties page: " + pnfe.getMessage());
160
			} catch (IOException ioe) {
161
				throw new AdminException("IO problem while initializing "
162
						+ "skins properties page:" + ioe.getMessage());
163
			} catch (ServletException se) {
164
				throw new AdminException("problem forwarding request while "
165
						+ "initializing skins properties page: " + se.getMessage());
166
			}
167

    
168
		} else {
169
			// The configuration form is being submitted and needs to be
170
			// processed.
171
			Vector<String> processingSuccess = new Vector<String>();
172
			Vector<String> processingErrors = new Vector<String>();
173
			Vector<String> validationErrors = new Vector<String>();
174

    
175
			try {
176
				//Default style is global.
177
				String defaultStyle = request.getParameter("application.default-style");
178
				PropertyService.setProperty("application.default-style", defaultStyle);
179
				
180
				// For each skin property, check if it is changed and save it
181
				Vector<String> skinNames = SkinUtil.getSkinNames();
182
				for (String skinName : skinNames) {
183
					PropertiesMetaData skinMetaData = 
184
						SkinPropertyService.getMetaData(skinName);
185
					Set<String> metaDataKeySet = skinMetaData.getKeys();
186
					for (String metaDataKey : metaDataKeySet) {
187
						MetaDataProperty metaDataProperty = 
188
							skinMetaData.getProperties().get(metaDataKey);
189
						String fieldType = metaDataProperty.getFieldType();
190
						String newValue = request.getParameter(skinName + "." + metaDataKey);
191
						if (fieldType != null && fieldType.equals("checkbox")) {
192
							if (newValue != null && newValue.equals("on")) {
193
								SkinPropertyService.checkAndSetProperty("true", skinName, metaDataKey);
194
							} else {
195
								SkinPropertyService.checkAndSetProperty("false", skinName, metaDataKey);
196
							}								
197
						} else {		
198
							SkinPropertyService.checkAndSetProperty(request, skinName, metaDataKey);
199
						}
200
					}
201

    
202
					// we need to write the options from memory to the
203
					// properties file
204
					SkinPropertyService.persistProperties(skinName);
205

    
206
					// Validate that the options provided are legitimate. Note
207
					// that we've allowed them to persist their entries. As of 
208
					// this point there is no other easy way to go back to the 
209
					// configure form and preserve their entries.
210
					validationErrors.addAll(validateOptions(request, skinName));
211

    
212
					// Try to create backup directories if necessary.
213
					String backupDir = PropertyService.getBackupDir();
214
					try {
215
						FileUtil.createDirectory(backupDir);
216
					} catch (IOException ioe) {	
217
						String errorString = "Could not create directory: " + backupDir +
218
							" : " + ioe.getMessage();
219
						logMetacat.error(errorString);
220
						validationErrors.add(errorString);
221
					}
222

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

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

    
306
		//TODO MCD validate options.
307

    
308
		return errorVector;
309
	}
310
}
(10-10/10)