### Eclipse Workspace Patch 1.0
#P dso-l1
Index: tests.unit.resources/com/tc/object/config/tc-config-includeexclude.xml
===================================================================
--- tests.unit.resources/com/tc/object/config/tc-config-includeexclude.xml (revision 0)
+++ tests.unit.resources/com/tc/object/config/tc-config-includeexclude.xml (revision 0)
@@ -0,0 +1,39 @@
+
+
+
+
+ development
+
+
+ %d/client-logs-%h
+
+
+
+
+
+
+
+
+
+
+ p.*
+
+ p.q.*
+
+ p.q.C
+
+
+ p.q.r.*
+
+ p.q.r.D
+
+
+
+
+
+
Index: src/com/tc/object/config/ConfigLoader.java
===================================================================
--- src/com/tc/object/config/ConfigLoader.java (revision 9740)
+++ src/com/tc/object/config/ConfigLoader.java (working copy)
@@ -19,6 +19,7 @@
import com.tc.util.ClassUtils.ClassSpec;
import com.terracottatech.config.AdditionalBootJarClasses;
import com.terracottatech.config.Autolock;
+import com.terracottatech.config.ClassExpression;
import com.terracottatech.config.DistributedMethods;
import com.terracottatech.config.DsoApplication;
import com.terracottatech.config.Include;
@@ -289,27 +290,35 @@
}
}
- private void loadInstrumentedClasses(InstrumentedClasses instrumentedClasses) {
+ private void loadInstrumentedClasses(InstrumentedClasses instrumentedClasses) throws ConfigurationSetupException {
if (instrumentedClasses != null) {
- Include[] includes = instrumentedClasses.getIncludeArray();
- for (int i = 0; includes != null && i < includes.length; i++) {
- Include include = includes[i];
- IncludeOnLoad includeOnLoad = new IncludeOnLoad();
- OnLoad onLoad = include.getOnLoad();
- if (onLoad != null) {
- if (onLoad.getExecute() != null) {
- includeOnLoad = new IncludeOnLoad(IncludeOnLoad.EXECUTE, onLoad.getExecute());
- } else if (onLoad.getMethod() != null) {
- includeOnLoad = new IncludeOnLoad(IncludeOnLoad.METHOD, onLoad.getMethod());
+ // Call selectPath() rather than using getIncludeArray and getExcludeArray(),
+ // because we need to preserve the relative order of includes and excludes.
+ XmlObject[] elements = instrumentedClasses.selectPath("*");
+ for (int i = 0; elements != null && i < elements.length; ++i) {
+ if (elements[i] instanceof Include) {
+ Include include = (Include) elements[i];
+ IncludeOnLoad includeOnLoad = new IncludeOnLoad();
+ OnLoad onLoad = include.getOnLoad();
+ if (onLoad != null) {
+ if (onLoad.getExecute() != null) {
+ includeOnLoad = new IncludeOnLoad(IncludeOnLoad.EXECUTE, onLoad.getExecute());
+ } else if (onLoad.getMethod() != null) {
+ includeOnLoad = new IncludeOnLoad(IncludeOnLoad.METHOD, onLoad.getMethod());
+ }
}
+ config.addInstrumentationDescriptor(new IncludedInstrumentedClass(include.getClassExpression(), include
+ .getHonorTransient(), false, includeOnLoad));
}
- config.addInstrumentationDescriptor(new IncludedInstrumentedClass(include.getClassExpression(), include
- .getHonorTransient(), false, includeOnLoad));
- }
-
- String[] excludeArray = instrumentedClasses.getExcludeArray();
- for (int i = 0; excludeArray != null && i < excludeArray.length; i++) {
- config.addInstrumentationDescriptor(new ExcludedInstrumentedClass(excludeArray[i]));
+ else if (elements[i] instanceof ClassExpression) {
+ String expr = ((ClassExpression)elements[i]).getStringValue();
+ config.addInstrumentationDescriptor(new ExcludedInstrumentedClass(expr));
+ }
+ else {
+ throw new ConfigurationSetupException(
+ "The following element was unexpected within an element:" +
+ elements[i]);
+ }
}
}
}
Index: tests.unit.resources/com/tc/object/config/tc-config-includeexclude2.xml
===================================================================
--- tests.unit.resources/com/tc/object/config/tc-config-includeexclude2.xml (revision 0)
+++ tests.unit.resources/com/tc/object/config/tc-config-includeexclude2.xml (revision 0)
@@ -0,0 +1,41 @@
+
+
+
+
+ development
+
+
+ %d/client-logs-%h
+
+
+
+
+
+
+
+
+
+
+ A*
+
+ ABC
+
+
+ AB*
+
+
+ ZY
+
+
+ Z*
+
+
+
+
+
+
Index: tests.unit/com/tc/object/config/IncludeExcludeOrderingTest.java
===================================================================
--- tests.unit/com/tc/object/config/IncludeExcludeOrderingTest.java (revision 0)
+++ tests.unit/com/tc/object/config/IncludeExcludeOrderingTest.java (revision 0)
@@ -0,0 +1,97 @@
+/*
+ * All content copyright (c) 2008 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All
+ * rights reserved.
+ */
+package com.tc.object.config;
+
+import org.apache.xmlbeans.XmlException;
+import org.apache.xmlbeans.XmlOptions;
+import org.apache.xmlbeans.impl.values.XmlValueOutOfRangeException;
+
+import com.tc.aspectwerkz.reflect.ClassInfo;
+import com.tc.aspectwerkz.reflect.impl.asm.AsmClassInfo;
+import com.tc.config.Loader;
+import com.tc.config.schema.setup.ConfigurationSetupException;
+import com.tc.logging.NullTCLogger;
+import com.tc.logging.TCLogger;
+import com.tc.object.BaseDSOTestCase;
+import com.terracottatech.config.Application;
+import com.terracottatech.config.TcConfigDocument;
+import com.terracottatech.config.TcConfigDocument.TcConfig;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class IncludeExcludeOrderingTest extends BaseDSOTestCase {
+
+ /**
+ * Verify that relative order of includes and excludes is preserved: a specific include placed after a more general
+ * exclude will win, and similarly a specific exclude will win after a general include.
+ */
+ public void testMoreSpecificOrdering() throws XmlException, IOException, ConfigurationSetupException {
+ DSOClientConfigHelper config = loadConfigFile("tc-config-includeexclude.xml");
+
+ System.out.println("The following warnings about unloadable classes [p/A*] are expected.");
+ ClassInfo classInfoA = AsmClassInfo.getClassInfo("p.A", getClass().getClassLoader());
+ assertTrue(config.shouldBeAdapted(classInfoA));
+
+ ClassInfo classInfoB = AsmClassInfo.getClassInfo("p.q.B", getClass().getClassLoader());
+ assertFalse(config.shouldBeAdapted(classInfoB));
+
+ ClassInfo classInfoC = AsmClassInfo.getClassInfo("p.q.C", getClass().getClassLoader());
+ assertTrue(config.shouldBeAdapted(classInfoC));
+
+ ClassInfo classInfoD = AsmClassInfo.getClassInfo("p.q.r.D", getClass().getClassLoader());
+ assertFalse(config.shouldBeAdapted(classInfoD));
+
+ ClassInfo classInfoE = AsmClassInfo.getClassInfo("p.q.r.E", getClass().getClassLoader());
+ assertTrue(config.shouldBeAdapted(classInfoE));
+ }
+
+ /**
+ * Verify that relative order of includes and excludes is preserved: a more general include placed after a more
+ * specific exclude will win, and similarly a more general exclude after a specific include. Note that this sort of
+ * content in a tc-config.xml is not very useful, and indeed at some point we might want to issue warnings.
+ */
+ public void testMoreGeneralOrdering() throws XmlException, IOException, ConfigurationSetupException {
+ DSOClientConfigHelper config = loadConfigFile("tc-config-includeexclude2.xml");
+
+ System.out.println("The following warnings about unloadable classes [A*] and [Z*] are expected.");
+ ClassInfo classInfoA = AsmClassInfo.getClassInfo("A", getClass().getClassLoader());
+ assertTrue(config.shouldBeAdapted(classInfoA));
+
+ ClassInfo classInfoC = AsmClassInfo.getClassInfo("ABC", getClass().getClassLoader());
+ assertTrue(config.shouldBeAdapted(classInfoC));
+
+ ClassInfo classInfoZ = AsmClassInfo.getClassInfo("Z", getClass().getClassLoader());
+ assertFalse(config.shouldBeAdapted(classInfoZ));
+
+ ClassInfo classInfoY = AsmClassInfo.getClassInfo("ZY", getClass().getClassLoader());
+ assertFalse(config.shouldBeAdapted(classInfoY));
+ }
+
+ /**
+ * Load a config file in the same way that normal instrumention is done.
+ * @see com.tc.ModulesLoader#loadConfiguration()
+ */
+ private DSOClientConfigHelper loadConfigFile(String fileName) throws IOException, XmlException,
+ ConfigurationSetupException {
+ InputStream configFile = getClass().getResourceAsStream(fileName);
+ TcConfigDocument tcConfigDocument = new Loader().parse(configFile, new XmlOptions().setLoadLineNumbers()
+ .setValidateOnSet());
+ TcConfig tcConfig = tcConfigDocument.getTcConfig();
+ Application application = tcConfig.getApplication();
+ assertNotNull(" tag not found - check file " + fileName, application);
+ TCLogger logger = new NullTCLogger();
+ DSOClientConfigHelper config = createClientConfigHelper();
+
+ ConfigLoader loader = new ConfigLoader(config, logger);
+ try {
+ loader.loadDsoConfig(application.getDso());
+ } catch (XmlValueOutOfRangeException e) {
+ fail(e.getMessage());
+ }
+ return config;
+ }
+
+}