001: package org.tigris.scarab.services;
002:
003: /* ================================================================
004: * Copyright (c) 2000-2002 CollabNet. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions are
008: * met:
009: *
010: * 1. Redistributions of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: *
013: * 2. Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in the
015: * documentation and/or other materials provided with the distribution.
016: *
017: * 3. The end-user documentation included with the redistribution, if
018: * any, must include the following acknowlegement: "This product includes
019: * software developed by Collab.Net <http://www.Collab.Net/>."
020: * Alternately, this acknowlegement may appear in the software itself, if
021: * and wherever such third-party acknowlegements normally appear.
022: *
023: * 4. The hosted project names must not be used to endorse or promote
024: * products derived from this software without prior written
025: * permission. For written permission, please contact info@collab.net.
026: *
027: * 5. Products derived from this software may not use the "Tigris" or
028: * "Scarab" names nor may "Tigris" or "Scarab" appear in their names without
029: * prior written permission of Collab.Net.
030: *
031: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
032: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
033: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
034: * IN NO EVENT SHALL COLLAB.NET OR ITS CONTRIBUTORS BE LIABLE FOR ANY
035: * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
036: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
037: * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
038: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
039: * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
040: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
041: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
042: *
043: * ====================================================================
044: *
045: * This software consists of voluntary contributions made by many
046: * individuals on behalf of Collab.Net.
047: */
048:
049: import java.lang.reflect.Method;
050: import java.sql.Connection;
051: import java.sql.Statement;
052: import java.sql.ResultSet;
053: import java.util.Locale;
054: import java.util.List;
055: import java.util.MissingResourceException;
056: import java.util.Iterator;
057:
058: import org.apache.fulcrum.BaseService;
059: import org.apache.fulcrum.InitializationException;
060: import org.apache.fulcrum.localization.Localization;
061: import org.apache.turbine.Turbine;
062:
063: import org.apache.torque.Torque;
064: import org.apache.torque.util.Criteria;
065:
066: import org.tigris.scarab.om.GlobalParameter;
067: import org.tigris.scarab.om.GlobalParameterManager;
068: import org.tigris.scarab.om.GlobalParameterPeer;
069: import org.tigris.scarab.util.Log;
070: import org.tigris.scarab.util.ScarabConstants;
071:
072: /**
073: * Transforms localization keys stored in the database into their
074: * respective localized values upon initial startup of Fulcrum.
075: *
076: * @author <a href="mailto:jmcnally@collab.net">John McNally</a>
077: * @version $Id: DatabaseInitializer.java 9318 2004-12-13 13:00:55Z dabbous $
078: */
079: public class DatabaseInitializer extends BaseService {
080: private static final String PRE_L10N = "pre-l10n";
081: private static final String STARTED_L10N = "started";
082: private static final String POST_L10N = "post-l10n";
083: private static final String DB_L10N_STATE = "db-l10n-state";
084:
085: // some old parameter keys for the http parameters
086: private static final String MODULE_DOMAIN = "module-domain";
087: private static final String MODULE_PORT = "module-port";
088: private static final String MODULE_SCHEME = "module-scheme";
089: private static final String MODULE_SCRIPT_NAME = "module-script-name";
090:
091: /**
092: * The values returned by {@link #getInputData()}.
093: */
094: private static final String[][] BEAN_METHODS = {
095: { "InitDbScarabBundle", "MITList", "Name" },
096: { "InitDbScarabBundle", "Attribute", "Name", "Description" },
097: { "InitDbScarabBundle", "AttributeOption", "Name" },
098: { "InitDbScarabBundle", "IssueType", "Name", "Description" },
099: { "InitDbScarabBundle", "AttributeGroup", "Name",
100: "Description" },
101: { "InitDbScarabBundle", "RModuleAttribute", "DisplayValue" },
102: { "InitDbScarabBundle", "Scope", "Name" } };
103:
104: /**
105: * Initializes the service by setting up Torque.
106: */
107: public void init() throws InitializationException {
108: try {
109: String dbState = GlobalParameterManager
110: .getString(DB_L10N_STATE);
111: if (PRE_L10N.equals(dbState)
112: || STARTED_L10N.equals(dbState)) {
113: long start = System.currentTimeMillis();
114: Log.get().info(
115: "New scarab database; localizing strings for '"
116: + ScarabConstants.DEFAULT_LOCALE
117: .getDisplayName() + "'...");
118: GlobalParameterManager.setString(DB_L10N_STATE,
119: STARTED_L10N);
120: initdb(ScarabConstants.DEFAULT_LOCALE);
121: GlobalParameterManager.setString(DB_L10N_STATE,
122: POST_L10N);
123: Log.get().info(
124: "Done localizing. Time elapsed = "
125: + (System.currentTimeMillis() - start)
126: / 1000.0 + " s");
127: }
128:
129: checkNewHttpParameters();
130: } catch (Exception e) {
131: e.printStackTrace();
132: throw new InitializationException(
133: "Failed to localize default data!", e); //EXCEPTION
134: }
135:
136: // indicate that the service initialized correctly
137: setInit(true);
138: }
139:
140: protected String[][] getInputData() {
141: return BEAN_METHODS;
142: }
143:
144: private void initdb(Locale defaultLocale) throws Exception {
145: String[][] methodNames = getInputData();
146: Class[] stringSig = { String.class };
147: Class[] critSig = { Criteria.class };
148:
149: for (int m = 0; m < methodNames.length; m++) {
150: String[] row = methodNames[m];
151: String omClassName = "org.tigris.scarab.om." + row[1];
152: Class peerClass = Class.forName(omClassName + "Peer");
153: Object peerObject = peerClass.newInstance();
154:
155: Method doSelect = peerClass.getMethod("doSelect", critSig);
156: Object[] critArg = { new Criteria() };
157: List omlist = (List) doSelect.invoke(peerObject, critArg);
158: if (!omlist.isEmpty()) {
159: Class omClass = Class.forName(omClassName);
160: int nbrBeanMethods = row.length - 2;
161: Method[] getters = new Method[nbrBeanMethods];
162: Method[] setters = new Method[nbrBeanMethods];
163: for (int n = 2; n < row.length; n++) {
164: getters[n - 2] = omClass.getMethod("get" + row[n],
165: null);
166: setters[n - 2] = omClass.getMethod("set" + row[n],
167: stringSig);
168: }
169: Method save = omClass.getMethod("save", null);
170:
171: Iterator i = omlist.iterator();
172: while (i.hasNext()) {
173: Object om = i.next();
174: for (int n = 0; n < getters.length; n++) {
175: Log.get().debug(
176: "Converting " + row[1] + '.'
177: + getters[n].getName());
178: String key = (String) getters[n].invoke(om,
179: null);
180: String value = null;
181:
182: // Oracle returns null on empty field.
183: if (key != null) {
184: try {
185: value = Localization.getString(row[0],
186: defaultLocale, key);
187: } catch (MissingResourceException e) {
188: Log.get().debug(
189: "Missing database initialization "
190: + "resource: "
191: + e.getMessage());
192: }
193: }
194: if (value != null) {
195: Object[] arg = { value };
196: setters[n].invoke(om, arg);
197: }
198: }
199: save.invoke(om, null);
200: }
201: }
202: }
203: }
204:
205: private void checkNewHttpParameters() throws Exception {
206: String oldDomain = GlobalParameterManager
207: .getString(ScarabConstants.HTTP_DOMAIN);
208: String oldScheme = GlobalParameterManager
209: .getString(ScarabConstants.HTTP_SCHEME);
210: String oldScriptName = GlobalParameterManager
211: .getString(ScarabConstants.HTTP_SCRIPT_NAME);
212: String oldPort = GlobalParameterManager
213: .getString(ScarabConstants.HTTP_PORT);
214:
215: if (oldDomain.equals("")) {
216: // installations with post-b15 but pre-b16 may have module
217: // specific values.
218: Criteria crit = new Criteria();
219: crit.add(GlobalParameterPeer.NAME, MODULE_DOMAIN);
220: List parameters = GlobalParameterPeer.doSelect(crit);
221: if (!parameters.isEmpty()) {
222: oldDomain = ((GlobalParameter) parameters.get(0))
223: .getValue();
224: }
225:
226: crit = new Criteria();
227: crit.add(GlobalParameterPeer.NAME, MODULE_SCHEME);
228: parameters = GlobalParameterPeer.doSelect(crit);
229: if (!parameters.isEmpty()) {
230: oldScheme = ((GlobalParameter) parameters.get(0))
231: .getValue();
232: }
233:
234: crit = new Criteria();
235: crit.add(GlobalParameterPeer.NAME, MODULE_SCRIPT_NAME);
236: parameters = GlobalParameterPeer.doSelect(crit);
237: if (!parameters.isEmpty()) {
238: oldScriptName = ((GlobalParameter) parameters.get(0))
239: .getValue();
240: }
241:
242: crit = new Criteria();
243: crit.add(GlobalParameterPeer.NAME, MODULE_PORT);
244: parameters = GlobalParameterPeer.doSelect(crit);
245: if (!parameters.isEmpty()) {
246: oldPort = ((GlobalParameter) parameters.get(0))
247: .getValue();
248: }
249: }
250:
251: String newValue = Turbine.getConfiguration().getString(
252: ScarabConstants.HTTP_DOMAIN);
253: if (newValue != null && newValue.trim().length() != 0
254: && !newValue.equals(oldDomain)) {
255: GlobalParameterManager.setString(
256: ScarabConstants.HTTP_DOMAIN, newValue);
257: fixIssueIdCounters(oldDomain, newValue);
258: }
259:
260: newValue = Turbine.getConfiguration().getString(
261: ScarabConstants.HTTP_SCHEME);
262: if (newValue != null && newValue.trim().length() != 0
263: && !newValue.equals(oldScheme)) {
264: GlobalParameterManager.setString(
265: ScarabConstants.HTTP_SCHEME, newValue);
266: }
267:
268: newValue = Turbine.getConfiguration().getString(
269: ScarabConstants.HTTP_SCRIPT_NAME);
270: if (newValue != null && newValue.trim().length() != 0
271: && !newValue.equals(oldScriptName)) {
272: GlobalParameterManager.setString(
273: ScarabConstants.HTTP_SCRIPT_NAME, newValue);
274: }
275:
276: newValue = Turbine.getConfiguration().getString(
277: ScarabConstants.HTTP_PORT);
278: if (newValue != null && newValue.trim().length() != 0
279: && !newValue.equals(oldPort)) {
280: GlobalParameterManager.setString(ScarabConstants.HTTP_PORT,
281: newValue);
282: }
283: }
284:
285: private void fixIssueIdCounters(String oldDomain, String newDomain)
286: throws Exception {
287: String sql = "select NEXT_ID from ID_TABLE where TABLE_NAME='ID_TABLE'";
288: Connection con = null;
289: try {
290: con = Torque.getConnection();
291: Statement s = con.createStatement();
292: ResultSet rs = s.executeQuery(sql);
293: int maxId = 0;
294: if (rs.next()) {
295: maxId = rs.getInt(1);
296: }
297: s.close();
298:
299: for (int id = 1000; id <= maxId; id++) {
300: sql = "select TABLE_NAME from ID_TABLE where ID_TABLE_ID="
301: + id;
302: s = con.createStatement();
303: rs = s.executeQuery(sql);
304: if (rs.next()) {
305: String oldKey = rs.getString(1);
306: s.close();
307: int hyphenPos = oldKey.indexOf('-');
308: String newKey = null;
309: if ((oldDomain == null || oldDomain.length() == 0)
310: && hyphenPos <= 0) {
311: newKey = newDomain + '-' + oldKey;
312: } else {
313: String prefix = oldKey.substring(0, hyphenPos);
314: String code = oldKey.substring(hyphenPos + 1);
315: if (prefix.equals(oldDomain)) {
316: newKey = newDomain + '-' + code;
317: }
318: }
319:
320: if (newKey != null) {
321: sql = "update ID_TABLE set TABLE_NAME='"
322: + newKey + "' where ID_TABLE_ID=" + id;
323: s = con.createStatement();
324: s.executeUpdate(sql);
325: s.close();
326: }
327: }
328: }
329: } finally {
330: if (con != null) {
331: con.close();
332: }
333: }
334: }
335: }
|