001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018:
019: package org.apache.jmeter.save.converters;
020:
021: import org.apache.jmeter.samplers.SampleSaveConfiguration;
022:
023: import com.thoughtworks.xstream.converters.MarshallingContext;
024: import com.thoughtworks.xstream.converters.UnmarshallingContext;
025: import com.thoughtworks.xstream.converters.reflection.ReflectionConverter;
026: import com.thoughtworks.xstream.converters.reflection.ReflectionProvider;
027: import com.thoughtworks.xstream.core.JVM;
028: import com.thoughtworks.xstream.io.HierarchicalStreamReader;
029: import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
030: import com.thoughtworks.xstream.mapper.Mapper;
031: import com.thoughtworks.xstream.mapper.MapperWrapper;
032:
033: /*
034: * Allow new fields to be added to the SampleSaveConfiguration without
035: * changing the output JMX file unless it is necessary.
036: *
037: * TODO work out how to make shouldSerializeMember() conditionally return true.
038: */
039: public class SampleSaveConfigurationConverter extends
040: ReflectionConverter {
041:
042: private static final ReflectionProvider rp = new JVM()
043: .bestReflectionProvider();
044:
045: private static final String TRUE = "true"; // $NON-NLS-1$
046:
047: // N.B. These must agree with the new member names in SampleSaveConfiguration
048: private static final String NODE_FILENAME = "fileName"; // $NON-NLS-1$
049: private static final String NODE_HOSTNAME = "hostname"; // $NON-NLS-1$
050: private static final String NODE_URL = "url"; // $NON-NLS-1$
051: private static final String NODE_BYTES = "bytes"; // $NON-NLS-1$
052: private static final String NODE_THREAD_COUNT = "threadCounts"; // $NON-NLS-1$
053: private static final String NODE_SAMPLE_COUNT = "sampleCount"; // $NON-NLS-1$
054:
055: // Additional member names which are currently not written out
056: private static final String NODE_DELIMITER = "delimiter"; // $NON-NLS-1$
057: private static final String NODE_PRINTMS = "printMilliseconds"; // $NON-NLS-1$
058:
059: static class MyWrapper extends MapperWrapper {
060:
061: public MyWrapper(Mapper wrapped) {
062: super (wrapped);
063: }
064:
065: public boolean shouldSerializeMember(Class definedIn,
066: String fieldName) {
067: if (SampleSaveConfiguration.class != definedIn)
068: return true;
069: // These are new fields; not saved unless true
070: if (fieldName.equals(NODE_BYTES))
071: return false;
072: if (fieldName.equals(NODE_URL))
073: return false;
074: if (fieldName.equals(NODE_FILENAME))
075: return false;
076: if (fieldName.equals(NODE_HOSTNAME))
077: return false;
078: if (fieldName.equals(NODE_THREAD_COUNT))
079: return false;
080: if (fieldName.equals(NODE_SAMPLE_COUNT))
081: return false;
082:
083: // These fields are not currently saved or restored
084: if (fieldName.equals(NODE_DELIMITER))
085: return false;
086: if (fieldName.equals(NODE_PRINTMS))
087: return false;
088: return true;
089: }
090: }
091:
092: public SampleSaveConfigurationConverter(Mapper arg0) {
093: super (new MyWrapper(arg0), rp);
094: }
095:
096: /**
097: * Returns the converter version; used to check for possible
098: * incompatibilities
099: */
100: public static String getVersion() {
101: return "$Revision: 593947 $"; // $NON-NLS-1$
102: }
103:
104: /*
105: * (non-Javadoc)
106: *
107: * @see com.thoughtworks.xstream.converters.Converter#canConvert(java.lang.Class)
108: */
109: public boolean canConvert(Class arg0) {
110: return arg0.equals(SampleSaveConfiguration.class);
111: }
112:
113: /*
114: * (non-Javadoc)
115: *
116: * @see com.thoughtworks.xstream.converters.Converter#marshal(java.lang.Object,
117: * com.thoughtworks.xstream.io.HierarchicalStreamWriter,
118: * com.thoughtworks.xstream.converters.MarshallingContext)
119: */
120: public void marshal(Object obj, HierarchicalStreamWriter writer,
121: MarshallingContext context) {
122: super .marshal(obj, writer, context); // Save most things
123:
124: SampleSaveConfiguration prop = (SampleSaveConfiguration) obj;
125:
126: // Save the new fields - but only if they are not the default
127: createNode(writer, prop.saveBytes(), NODE_BYTES);
128: createNode(writer, prop.saveUrl(), NODE_URL);
129: createNode(writer, prop.saveFileName(), NODE_FILENAME);
130: createNode(writer, prop.saveHostname(), NODE_HOSTNAME);
131: createNode(writer, prop.saveThreadCounts(), NODE_THREAD_COUNT);
132: createNode(writer, prop.saveSampleCount(), NODE_SAMPLE_COUNT);
133: }
134:
135: // Helper method to simplify marshall routine
136: private void createNode(HierarchicalStreamWriter writer,
137: boolean save, String node) {
138: if (!save)
139: return;
140: writer.startNode(node);
141: writer.setValue(TRUE);
142: writer.endNode();
143: }
144:
145: /*
146: *
147: */
148: public Object unmarshal(HierarchicalStreamReader reader,
149: UnmarshallingContext context) {
150: final Class this Class = SampleSaveConfiguration.class;
151: final Class requiredType = context.getRequiredType();
152: if (requiredType != this Class) {
153: throw new IllegalArgumentException("Unexpected class: "
154: + requiredType.getName());
155: }
156: SampleSaveConfiguration result = new SampleSaveConfiguration();
157: result.setBytes(false); // Maintain backward compatibility (bytes was not in the JMX file)
158: while (reader.hasMoreChildren()) {
159: reader.moveDown();
160: String nn = reader.getNodeName();
161: if (!"formatter".equals(nn)) {// Skip formatter (if present) bug 42674 $NON-NLS-1$
162: String fieldName = mapper.realMember(this Class, nn);
163: java.lang.reflect.Field field = reflectionProvider
164: .getField(this Class, fieldName);
165: Class type = field.getType();
166: Object value = unmarshallField(context, result, type,
167: field);
168: reflectionProvider.writeField(result, nn, value,
169: thisClass);
170: }
171: reader.moveUp();
172: }
173: return result;
174: }
175: }
|