patternjavaMinor
Setting various types of properties on a JCR node
Viewed 0 times
jcrpropertiesnodesettingtypesvarious
Problem
This code checks value's type and cast it into appropriate type, then puts it into a
The checking looks long and boring. Is there a way to refactor it? I'm using Java 7.
```
/**
* Set node's property.
*/
public static void setProperty(Node node, String propertyName, Object propertyValue) throws RepositoryException {
if (node == null) {
throw new IllegalArgumentException("Something wrong");
}
if (propertyName == null) {
throw new IllegalArgumentException("Property name is invalid");
}
if (propertyValue == null) {
node.setProperty(propertyName, (Value) null);
} else if (propertyValue instanceof Value) {
node.setProperty(propertyName, (Value) propertyValue);
} else if (propertyValue instanceof Node) {
node.setProperty(propertyName, (Node) propertyValue);
} else if (propertyValue instanceof Binary) {
node.setProperty(propertyName, (Binary) propertyValue);
} else if (propertyValue instanceof Calendar) {
node.setProperty(propertyName, (Calendar) propertyValue);
} else if (propertyValue instanceof Date) {
Calendar cal = Calendar.getInstance();
cal.setTime((Date) propertyValue);
node.setProperty(propertyName, cal);
} else if (propertyValue instanceof BigDecimal) {
node.setProperty(propertyName, (BigDecimal) propertyValue);
} else if (propertyValue instanceof String) {
node.setProperty(propertyName, (String) propertyValue);
} else if (propertyValue instanceof Long) {
node.setProperty(propertyName, ((Long) propertyValue).longValue());
} else if (propertyValue instanceof Double) {
node.setProperty(propertyName, (Double) propertyValue);
} else if (propertyValue instanceof Boolean) {
node.setProperty(propertyName, (Boolean) propertyValue);
} else if (propertyValue instanceof InputStream) {
node.setProperty(propertyName, inputStreamToBinary((InputStream) propertyValue
javax.jcr.Node.The checking looks long and boring. Is there a way to refactor it? I'm using Java 7.
```
/**
* Set node's property.
*/
public static void setProperty(Node node, String propertyName, Object propertyValue) throws RepositoryException {
if (node == null) {
throw new IllegalArgumentException("Something wrong");
}
if (propertyName == null) {
throw new IllegalArgumentException("Property name is invalid");
}
if (propertyValue == null) {
node.setProperty(propertyName, (Value) null);
} else if (propertyValue instanceof Value) {
node.setProperty(propertyName, (Value) propertyValue);
} else if (propertyValue instanceof Node) {
node.setProperty(propertyName, (Node) propertyValue);
} else if (propertyValue instanceof Binary) {
node.setProperty(propertyName, (Binary) propertyValue);
} else if (propertyValue instanceof Calendar) {
node.setProperty(propertyName, (Calendar) propertyValue);
} else if (propertyValue instanceof Date) {
Calendar cal = Calendar.getInstance();
cal.setTime((Date) propertyValue);
node.setProperty(propertyName, cal);
} else if (propertyValue instanceof BigDecimal) {
node.setProperty(propertyName, (BigDecimal) propertyValue);
} else if (propertyValue instanceof String) {
node.setProperty(propertyName, (String) propertyValue);
} else if (propertyValue instanceof Long) {
node.setProperty(propertyName, ((Long) propertyValue).longValue());
} else if (propertyValue instanceof Double) {
node.setProperty(propertyName, (Double) propertyValue);
} else if (propertyValue instanceof Boolean) {
node.setProperty(propertyName, (Boolean) propertyValue);
} else if (propertyValue instanceof InputStream) {
node.setProperty(propertyName, inputStreamToBinary((InputStream) propertyValue
Solution
My idea would be to encapsulate the job of casting and converting into some kind of a
I would use an
Then I want to hide this
Combine them together:
Strategy pattern.I would use an
enum for that, namely NodeSettingStrategy:public static enum NodeSettingValueStrategy {
UNKNOWN(null) {
@Override
public void set(Node node, String propertyName, Object value) {
throw new IllegalArgumentException("Cannot set property to a value of type " + value.getClass());
}
},
DATE(Date.class) {
@Override
public void set(Node node, String propertyName, Object value) {
node.setProperty(propertyName, (Long) value);
}
},
LONG_PRIMITIVE(long.class) {
@Override
public void set(Node node, String propertyName, Object value) {
node.setProperty(propertyName, (long) value);
}
},
LONG(Long.class) {
@Override
public void set(Node node, String propertyName, Object value) {
node.setProperty(propertyName, (Long) value);
}
},
STRING(String.class) {
@Override
public void set(Node node, String propertyName, Object value) {
node.setProperty(propertyName, (String) value);
}
},
NODE(Node.class) {
@Override
public void set(Node node, String propertyName, Object value) {
node.setProperty(propertyName, (Node) value);
}
};
private final Class supportedType;
private NodeSettingValueStrategy(Class supportedType) {
this.supportedType = supportedType;
}
public static NodeSettingValueStrategy of(Class type) {
for (NodeSettingValueStrategy strategy : NodeSettingValueStrategy.values()) {
if (strategy.supportedType == type) {
return strategy;
}
}
return NodeSettingValueStrategy.UNKNOWN;
}
public abstract void set(Node node, String propertyName, Object value);
}Then I want to hide this
NodeSettingStrategy by a thin abstraction, namely NodeSetter:public static class NodeValueSetter {
private final NodeSettingValueStrategy strategy;
private final String propertyName;
private final Object value;
private NodeValueSetter(NodeSettingValueStrategy strategy, String propertyName, Object value) {
this.strategy = strategy;
this.propertyName = propertyName;
this.value = value;
}
public void setTo(Node node) {
strategy.set(node, propertyName, value);
}
public static NodeValueSetter of(final String propertyName, final Object value) {
NodeSettingValueStrategy settingStrategy = NodeSettingValueStrategy.of(value.getClass());
return new NodeValueSetter(settingStrategy, propertyName, value);
}
}Combine them together:
@Test
public void should_able_to_set_property() throws Exception {
Node node = new Node();
Node givenNode = new Node();
String someString = "The brown fox jumps over a lazy dog";
long givenLong = 234234234234L;
for (NodeValueSetter setter : Arrays.asList(
NodeValueSetter.of("a-string", someString),
NodeValueSetter.of("a-number", givenLong),
NodeValueSetter.of("a-node", givenNode))) {
setter.setTo(node);
}
assertThat(node.getProperty("a-string"), is(someString));
assertThat(node.getProperty("a-number"), is(givenLong));
assertThat(node.getProperty("a-node"), is(givenNode));
}Code Snippets
public static enum NodeSettingValueStrategy {
UNKNOWN(null) {
@Override
public void set(Node node, String propertyName, Object value) {
throw new IllegalArgumentException("Cannot set property to a value of type " + value.getClass());
}
},
DATE(Date.class) {
@Override
public void set(Node node, String propertyName, Object value) {
node.setProperty(propertyName, (Long) value);
}
},
LONG_PRIMITIVE(long.class) {
@Override
public void set(Node node, String propertyName, Object value) {
node.setProperty(propertyName, (long) value);
}
},
LONG(Long.class) {
@Override
public void set(Node node, String propertyName, Object value) {
node.setProperty(propertyName, (Long) value);
}
},
STRING(String.class) {
@Override
public void set(Node node, String propertyName, Object value) {
node.setProperty(propertyName, (String) value);
}
},
NODE(Node.class) {
@Override
public void set(Node node, String propertyName, Object value) {
node.setProperty(propertyName, (Node) value);
}
};
private final Class<?> supportedType;
private NodeSettingValueStrategy(Class<?> supportedType) {
this.supportedType = supportedType;
}
public static NodeSettingValueStrategy of(Class<?> type) {
for (NodeSettingValueStrategy strategy : NodeSettingValueStrategy.values()) {
if (strategy.supportedType == type) {
return strategy;
}
}
return NodeSettingValueStrategy.UNKNOWN;
}
public abstract void set(Node node, String propertyName, Object value);
}public static class NodeValueSetter {
private final NodeSettingValueStrategy strategy;
private final String propertyName;
private final Object value;
private NodeValueSetter(NodeSettingValueStrategy strategy, String propertyName, Object value) {
this.strategy = strategy;
this.propertyName = propertyName;
this.value = value;
}
public void setTo(Node node) {
strategy.set(node, propertyName, value);
}
public static NodeValueSetter of(final String propertyName, final Object value) {
NodeSettingValueStrategy settingStrategy = NodeSettingValueStrategy.of(value.getClass());
return new NodeValueSetter(settingStrategy, propertyName, value);
}
}@Test
public void should_able_to_set_property() throws Exception {
Node node = new Node();
Node givenNode = new Node();
String someString = "The brown fox jumps over a lazy dog";
long givenLong = 234234234234L;
for (NodeValueSetter setter : Arrays.asList(
NodeValueSetter.of("a-string", someString),
NodeValueSetter.of("a-number", givenLong),
NodeValueSetter.of("a-node", givenNode))) {
setter.setTo(node);
}
assertThat(node.getProperty("a-string"), is(someString));
assertThat(node.getProperty("a-number"), is(givenLong));
assertThat(node.getProperty("a-node"), is(givenNode));
}Context
StackExchange Code Review Q#129820, answer score: 3
Revisions (0)
No revisions yet.