001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tc;
006:
007: import org.apache.commons.io.CopyUtils;
008: import org.apache.commons.io.IOUtils;
009: import org.apache.xmlbeans.XmlException;
010: import org.apache.xmlbeans.XmlObject;
011: import org.apache.xmlbeans.XmlOptions;
012:
013: import com.tc.config.Loader;
014: import com.tc.config.schema.migrate.ConfigUpdateException;
015: import com.tc.object.tools.BootJarSignature;
016: import com.tc.pattern.PatternHelper;
017: import com.tc.servers.ServerSelection;
018: import com.terracottatech.config.AdditionalBootJarClasses;
019: import com.terracottatech.config.Application;
020: import com.terracottatech.config.DsoApplication;
021: import com.terracottatech.config.Include;
022: import com.terracottatech.config.InstrumentedClasses;
023: import com.terracottatech.config.Server;
024: import com.terracottatech.config.Servers;
025: import com.terracottatech.config.TcConfigDocument;
026: import com.terracottatech.config.TransientFields;
027: import com.terracottatech.config.WebApplication;
028: import com.terracottatech.config.WebApplications;
029: import com.terracottatech.config.TcConfigDocument.TcConfig;
030:
031: import java.io.File;
032: import java.io.FileOutputStream;
033: import java.io.IOException;
034: import java.io.InputStream;
035: import java.io.OutputStream;
036: import java.util.ArrayList;
037: import java.util.List;
038:
039: import javax.swing.SwingUtilities;
040:
041: /*
042: * TODO: factor out a BaseConfigurationHelper that is shared with the Eclipse plugin's ConfigurationHelper and anyone
043: * else that needs basic logic about the config, such as isTransient(String fieldName).
044: */
045:
046: public class ConfigHelper {
047: private Loader m_configLoader;
048: private XmlOptions m_xmlOptions;
049: private File m_configFile;
050: private TcConfig m_config;
051:
052: private static final String TC_INSTALL_DIR = SessionIntegratorFrame
053: .getTCInstallDir();
054:
055: private static final String TOMCAT_SANDBOX = SessionIntegratorFrame
056: .getSandBoxRoot();
057:
058: private static final String FS = System
059: .getProperty("file.separator");
060:
061: private static final String CUSTOM_BOOT_JAR_PATH = TC_INSTALL_DIR
062: + FS + "lib" + FS + "dso-boot" + FS
063: + getBootJarNameForThisVM();
064:
065: private static final int DEFAULT_JMX_PORT = 9520;
066:
067: public ConfigHelper() {
068: super ();
069: }
070:
071: public ConfigHelper(ServerSelection selection) {
072: super ();
073:
074: String serverName = selection.getSelectedServer().getName();
075:
076: m_configLoader = new Loader();
077: m_xmlOptions = createXmlOptions();
078: m_configFile = new File(TOMCAT_SANDBOX + FS + serverName + FS
079: + "tc-config.xml");
080:
081: testUpdateConfig();
082: }
083:
084: private void testUpdateConfig() {
085: try {
086: if (m_configFile.exists()) {
087: if (m_configLoader.testIsOld(m_configFile)) {
088: m_configLoader.updateToCurrent(m_configFile);
089: }
090: }
091: } catch (ConfigUpdateException cue) {
092: // TODO: we need to handle this
093: } catch (Exception e) {/**/
094: }
095: }
096:
097: public String getConfigFilePath() {
098: return m_configFile.getAbsolutePath();
099: }
100:
101: public File getConfigFile() {
102: return m_configFile;
103: }
104:
105: public TcConfig getConfig() {
106: return m_config;
107: }
108:
109: public void setConfig(TcConfig newConfig) {
110: m_config = newConfig;
111: }
112:
113: public TcConfig ensureConfig() {
114: TcConfig config = getConfig();
115:
116: if (config == null) {
117: try {
118: config = load();
119: } catch (Exception e) {
120: e.printStackTrace();
121: m_config = config = TcConfig.Factory.newInstance();
122: }
123: }
124:
125: return config;
126: }
127:
128: public int getJmxPort() {
129: TcConfig config = ensureConfig();
130: Servers servers = config.getServers();
131:
132: if (servers == null) {
133: servers = config.addNewServers();
134: }
135:
136: if (servers.sizeOfServerArray() == 0) {
137: servers.addNewServer();
138: save();
139: }
140:
141: Server server = servers.getServerArray(0);
142: int port = server.isSetJmxPort() ? server.getJmxPort()
143: : DEFAULT_JMX_PORT;
144:
145: return port;
146: }
147:
148: public DsoApplication getDsoApplication() {
149: TcConfig config = getConfig();
150:
151: if (config != null) {
152: Application app = config.getApplication();
153: return app != null ? app.getDso() : null;
154: }
155:
156: return null;
157: }
158:
159: public DsoApplication ensureDsoApplication() {
160: DsoApplication dsoApp = null;
161: TcConfig config = ensureConfig();
162:
163: if (config != null) {
164: Application app = config.getApplication();
165:
166: if (app == null) {
167: app = config.addNewApplication();
168: }
169:
170: if ((dsoApp = app.getDso()) == null) {
171: dsoApp = app.addNewDso();
172: dsoApp.addNewInstrumentedClasses();
173: }
174: }
175:
176: return dsoApp;
177: }
178:
179: public TcConfig load() throws Exception {
180: File configFile = getConfigFile();
181: TcConfigDocument configDoc;
182:
183: configDoc = m_configLoader.parse(configFile, m_xmlOptions);
184: m_config = configDoc.getTcConfig();
185:
186: return m_config;
187: }
188:
189: public List validate(String xmlText) throws IOException,
190: XmlException {
191: TcConfigDocument configDoc = m_configLoader.parse(xmlText,
192: m_xmlOptions);
193: TcConfig config = configDoc.getTcConfig();
194: List errors = new ArrayList();
195:
196: if (config != null) {
197: m_xmlOptions.setErrorListener(errors);
198: configDoc.validate(m_xmlOptions);
199: m_xmlOptions.setErrorListener(null);
200: }
201:
202: return errors;
203: }
204:
205: public void save() {
206: TcConfigDocument configDoc = TcConfigDocument.Factory
207: .newInstance();
208: InputStream inStream = null;
209: OutputStream outStream = null;
210:
211: try {
212: if (m_config != null) {
213: configDoc.setTcConfig(m_config);
214:
215: inStream = configDoc.newInputStream(getXmlOptions());
216: outStream = new FileOutputStream(m_configFile);
217:
218: CopyUtils.copy(inStream, outStream);
219: }
220: } catch (Exception e) {
221: openError("Error saving '" + m_configFile.getName() + "'",
222: e);
223: } finally {
224: IOUtils.closeQuietly(inStream);
225: IOUtils.closeQuietly(outStream);
226: }
227: }
228:
229: public String getConfigText() {
230: TcConfig config = getConfig();
231: InputStream inStream = null;
232: String text = null;
233:
234: try {
235: if (config != null) {
236: TcConfigDocument configDoc = TcConfigDocument.Factory
237: .newInstance();
238:
239: configDoc.setTcConfig(m_config);
240:
241: inStream = configDoc.newInputStream(getXmlOptions());
242: text = IOUtils.toString(inStream);
243: }
244: } catch (Exception e) {
245: openError("Error getting config text", e);
246: } finally {
247: IOUtils.closeQuietly(inStream);
248: }
249:
250: return text;
251: }
252:
253: public void save(String xmlText) {
254: TcConfigDocument configDoc = null;
255: InputStream inStream = null;
256: OutputStream outStream = null;
257:
258: try {
259: configDoc = m_configLoader.parse(xmlText, m_xmlOptions);
260: m_config = configDoc.getTcConfig();
261:
262: if (m_config != null) {
263: inStream = configDoc.newInputStream(getXmlOptions());
264: outStream = new FileOutputStream(m_configFile);
265:
266: CopyUtils.copy(inStream, outStream);
267: }
268: } catch (Exception e) {
269: openError("Error saving '" + m_configFile.getName() + "'",
270: e);
271: } finally {
272: IOUtils.closeQuietly(inStream);
273: IOUtils.closeQuietly(outStream);
274: }
275: }
276:
277: public void saveAs(File file, String xmlText) {
278: TcConfigDocument configDoc = null;
279: InputStream inStream = null;
280: OutputStream outStream = null;
281:
282: try {
283: configDoc = m_configLoader.parse(xmlText, m_xmlOptions);
284: m_config = configDoc.getTcConfig();
285:
286: if (m_config != null) {
287: inStream = configDoc.newInputStream(getXmlOptions());
288: outStream = new FileOutputStream(file);
289:
290: CopyUtils.copy(inStream, outStream);
291: }
292: } catch (Exception e) {
293: openError("Error saving '" + file.getName() + "'", e);
294: } finally {
295: IOUtils.closeQuietly(inStream);
296: IOUtils.closeQuietly(outStream);
297: }
298: }
299:
300: public void openError(final String msg, final Throwable t) {
301: if (SwingUtilities.isEventDispatchThread()) {
302: ErrorDialog d = new ErrorDialog(msg, t);
303: d.setVisible(true);
304: } else {
305: SwingUtilities.invokeLater(new Runnable() {
306: public void run() {
307: ErrorDialog d = new ErrorDialog(msg, t);
308: d.setVisible(true);
309: }
310: });
311: }
312: }
313:
314: public static String getCustomBootJarPath() {
315: return CUSTOM_BOOT_JAR_PATH;
316: }
317:
318: public static File getCustomBootJarFile() {
319: return new File(getCustomBootJarPath());
320: }
321:
322: public boolean ensureWebApplication(String name) {
323: DsoApplication dsoApp = ensureDsoApplication();
324:
325: if (dsoApp != null) {
326: WebApplications apps = dsoApp.getWebApplications();
327:
328: if (apps == null) {
329: apps = dsoApp.addNewWebApplications();
330: }
331:
332: WebApplication[] webApps = apps.getWebApplicationArray();
333: for (int i = 0; i < webApps.length; i++) {
334: if (webApps[i].getStringValue().equals(name)) {
335: return false;
336: }
337: }
338:
339: WebApplication webApp = apps.addNewWebApplication();
340: webApp.setStringValue(name);
341:
342: return true;
343: }
344:
345: return false;
346: }
347:
348: public boolean removeWebApplication(String name) {
349: DsoApplication dsoApp = getDsoApplication();
350:
351: if (dsoApp != null) {
352: WebApplications apps = dsoApp.getWebApplications();
353:
354: if (apps != null) {
355: WebApplication[] appNames = apps
356: .getWebApplicationArray();
357:
358: for (int i = 0; i < appNames.length; i++) {
359: if (appNames[i].getStringValue().equals(name)) {
360: apps.removeWebApplication(i);
361: if (apps.sizeOfWebApplicationArray() == 0) {
362: dsoApp.unsetWebApplications();
363: }
364: return true;
365: }
366: }
367: }
368: }
369:
370: return false;
371: }
372:
373: public InstrumentedClasses ensureInstrumentedClasses() {
374: DsoApplication dsoApp = ensureDsoApplication();
375: if (!dsoApp.isSetInstrumentedClasses()) {
376: dsoApp.addNewInstrumentedClasses();
377: }
378: return dsoApp.getInstrumentedClasses();
379: }
380:
381: public boolean isAdaptable(String classExpr) {
382: InstrumentedClasses classes = ensureInstrumentedClasses();
383: int size = classes.sizeOfIncludeArray();
384: Include include;
385: String expr;
386:
387: for (int i = 0; i < size; i++) {
388: include = classes.getIncludeArray(i);
389: expr = include.getClassExpression();
390:
391: if (PatternHelper.getHelper().matchesClass(expr, classExpr)) {
392: return true;
393: }
394: }
395:
396: return false;
397: }
398:
399: public void ensureAdaptable(String classExpr) {
400: if (!isAdaptable(classExpr)) {
401: ensureInstrumentedClasses().addNewInclude()
402: .setClassExpression(classExpr);
403: }
404: }
405:
406: public Include includeRuleFor(String classExpr) {
407: TcConfig config = getConfig();
408:
409: if (config != null) {
410: InstrumentedClasses classes = ensureInstrumentedClasses();
411:
412: if (classes != null) {
413: XmlObject[] objects = classes.selectPath("*");
414:
415: if (objects != null && objects.length > 0) {
416: for (int i = objects.length - 1; i >= 0; i--) {
417: XmlObject object = objects[i];
418:
419: if (object instanceof Include) {
420: String expr = ((Include) object)
421: .getClassExpression();
422: if (expr != null && expr.equals(classExpr)) {
423: return (Include) object;
424: }
425: }
426: }
427: }
428: }
429: }
430:
431: return null;
432: }
433:
434: public Include ensureIncludeRuleFor(String classExpr) {
435: Include include = includeRuleFor(classExpr);
436:
437: if (include == null) {
438: include = ensureInstrumentedClasses().addNewInclude();
439: include.setClassExpression(classExpr);
440: }
441:
442: return include;
443: }
444:
445: public void ensureNotAdaptable(String classExpr) {
446: InstrumentedClasses classes = ensureInstrumentedClasses();
447: int size = classes.sizeOfIncludeArray();
448: Include include;
449: String expr;
450:
451: for (int i = size - 1; i >= 0; i--) {
452: include = classes.getIncludeArray(i);
453: expr = include.getClassExpression();
454:
455: if (PatternHelper.getHelper().matchesClass(expr, classExpr)) {
456: classes.removeInclude(i);
457: }
458: }
459:
460: if (classes.sizeOfExcludeArray() == 0
461: && classes.sizeOfIncludeArray() == 0) {
462: getDsoApplication().unsetInstrumentedClasses();
463: }
464: }
465:
466: public TransientFields ensureTransientFields() {
467: DsoApplication dsoApp = ensureDsoApplication();
468: if (!dsoApp.isSetTransientFields()) {
469: dsoApp.addNewTransientFields();
470: }
471: return dsoApp.getTransientFields();
472: }
473:
474: private TransientFields getTransientFields() {
475: DsoApplication dsoApp = getDsoApplication();
476: return dsoApp != null ? dsoApp.getTransientFields() : null;
477: }
478:
479: public boolean isTransient(String fieldName) {
480: TcConfig config = getConfig();
481:
482: if (config != null) {
483: TransientFields transients = getTransientFields();
484:
485: if (transients != null) {
486: for (int i = 0; i < transients.sizeOfFieldNameArray(); i++) {
487: if (fieldName.equals(transients
488: .getFieldNameArray(i))) {
489: return true;
490: }
491: }
492: }
493: }
494:
495: return false;
496: }
497:
498: public void ensureTransient(String fieldName) {
499: if (!isTransient(fieldName)) {
500: ensureTransientFields().addFieldName(fieldName);
501: }
502: }
503:
504: public void ensureNotTransient(String fieldName) {
505: TransientFields transients = ensureTransientFields();
506: int count = transients.sizeOfFieldNameArray();
507:
508: for (int i = 0; i < count; i++) {
509: if (fieldName.equals(transients.getFieldNameArray(i))) {
510: transients.removeFieldName(i);
511: if (transients.sizeOfFieldNameArray() == 0) {
512: getDsoApplication().unsetTransientFields();
513: }
514: return;
515: }
516: }
517: }
518:
519: public AdditionalBootJarClasses ensureAdditionalBootJarClasses() {
520: DsoApplication dsoApp = ensureDsoApplication();
521: if (!dsoApp.isSetAdditionalBootJarClasses()) {
522: dsoApp.addNewAdditionalBootJarClasses();
523: }
524: return dsoApp.getAdditionalBootJarClasses();
525: }
526:
527: private AdditionalBootJarClasses getAdditionalBootJarClasses() {
528: DsoApplication dsoApp = getDsoApplication();
529: return dsoApp != null ? dsoApp.getAdditionalBootJarClasses()
530: : null;
531: }
532:
533: public boolean isBootJarClass(String className) {
534: AdditionalBootJarClasses classes = getAdditionalBootJarClasses();
535:
536: if (classes != null) {
537: String[] includes = classes.getIncludeArray();
538:
539: for (int i = 0; i < includes.length; i++) {
540: if (PatternHelper.getHelper().matchesClass(includes[i],
541: className)) {
542: return true;
543: }
544: }
545: }
546:
547: return false;
548: }
549:
550: public void ensureBootJarClass(String typeName) {
551: if (!isBootJarClass(typeName)) {
552: ensureAdditionalBootJarClasses().addInclude(typeName);
553: }
554: }
555:
556: public void ensureNotBootJarClass(String typeName) {
557: AdditionalBootJarClasses bootClasses = getAdditionalBootJarClasses();
558:
559: if (bootClasses != null) {
560: int count = bootClasses.sizeOfIncludeArray();
561:
562: for (int i = 0; i < count; i++) {
563: if (typeName.equals(bootClasses.getIncludeArray(i))) {
564: bootClasses.removeInclude(i);
565: if (bootClasses.sizeOfIncludeArray() == 0) {
566: getDsoApplication()
567: .unsetAdditionalBootJarClasses();
568: }
569: return;
570: }
571: }
572: }
573: }
574:
575: private XmlOptions createXmlOptions() {
576: XmlOptions opts = new XmlOptions();
577:
578: opts.setLoadLineNumbers();
579: opts.setSavePrettyPrint();
580: opts.setSavePrettyPrintIndent(2);
581: opts.remove(XmlOptions.LOAD_STRIP_WHITESPACE);
582: opts.remove(XmlOptions.LOAD_STRIP_COMMENTS);
583: opts.remove(XmlOptions.VALIDATE_ON_SET);
584:
585: return opts;
586: }
587:
588: public XmlOptions getXmlOptions() {
589: return m_xmlOptions;
590: }
591:
592: private static String getBootJarNameForThisVM() {
593: try {
594: return BootJarSignature.getBootJarNameForThisVM();
595: } catch (Exception e) {
596: return "dso-boot.jar";
597: }
598: }
599: }
|