I am trying to implement a crossfield validation (JSR-303) with a custom annotation on class level. However the isValid method is not called (but the initialize method).
So my question is: Why is the isValid method not being called for this class level validator? Defining it on property level works!
I tried it on JBoss AS 7 and Websphere AS 8.
Here is the code and a JUnit test (which works)
Test.java
public class Test {
#org.junit.Test
public void test() throws ParseException {
Person person = new Person();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMDD");
person.setPartyClosingDateFrom(new Date());
person.setPartyClosingDateTo(sdf.parse("20120210"));
Set<ConstraintViolation<Person>> violations = Validation.buildDefaultValidatorFactory().getValidator().validate(person);
for(ConstraintViolation<Person> violation : violations) {
System.out.println("Message:- " + violation.getMessage());
}
}
}
DateCompare.java
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
#Target({ TYPE})
#Retention(RUNTIME)
#Constraint(validatedBy = DateCompareValidator.class)
#Documented
public #interface DateCompare {
/** First date. */
String firstDate();
/** Second date. */
String secondDate();
Class<?>[] constraints() default {};
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
String message() default "totally wrong, dude!";
DateValidator.DateComparisonMode matchMode() default
DateValidator.DateComparisonMode.EQUAL;
}
DateCompareValidator.java
public class DateCompareValidator implements ConstraintValidator<DateCompare, Object> {
/** describes the mode the validator should use**/
private DateValidator.DateComparisonMode comparisonMode;
/** The first date field name. */
private String firstDateFieldName;
/** The second date field name. */
private String secondDateFieldName;
/** the message to be used **/
private String messageKey = "failure";
/**
* Initialize.
*
* This method is used to set the parameters ans is REQUIRED even if you don't use any parameters
*
* #param constraintAnnotation the constraint annotation
*/
#Override
public void initialize(final DateCompare constraintAnnotation) {
this.comparisonMode = constraintAnnotation.matchMode();
this.firstDateFieldName = constraintAnnotation.firstDate();
this.secondDateFieldName = constraintAnnotation.secondDate();
}
/**
* Checks if it is valid.
*
* #param target the target
* #param context the context
* #return true, if is valid
*/
#Override
public boolean isValid(final Object target, final ConstraintValidatorContext context) {
boolean isValid = true;
final Date valueDate1 = DateCompareValidator.getPropertyValue(Date.class, this.firstDateFieldName, target);
final Date valueDate2 = DateCompareValidator.getPropertyValue(Date.class, this.secondDateFieldName, target);
if (isValid) {
isValid = DateValidator.isValid(valueDate1, valueDate2, this.comparisonMode);
} else {
// at this point comparisonMode does not fit tp the result and we have to
// design an error Message
final ResourceBundle messageBundle = ResourceBundle.getBundle("resources.messages");
final MessageFormat message = new MessageFormat(messageBundle.getString(this.messageKey));
final Object[] messageArguments = { messageBundle.getString(this.messageKey + "." + this.comparisonMode) };
// replace the default-message with the one we just created
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate(message.format(messageArguments)).addConstraintViolation();
isValid = false;
}
return isValid;
}
public static <T> T getPropertyValue(final Class<T> requiredType, final String propertyName, final Object instance) {
if (requiredType == null) {
throw new IllegalArgumentException("Invalid argument. requiredType must NOT be null!");
}
if (propertyName == null) {
throw new IllegalArgumentException("Invalid argument. PropertyName must NOT be null!");
}
if (instance == null) {
throw new IllegalArgumentException("Invalid argument. Object instance must NOT be null!");
}
T returnValue = null;
try {
final PropertyDescriptor descriptor = new PropertyDescriptor(propertyName, instance.getClass());
final Method readMethod = descriptor.getReadMethod();
if (readMethod == null) {
throw new IllegalStateException("Property '" + propertyName + "' of " + instance.getClass().getName()
+ " is NOT readable!");
}
if (requiredType.isAssignableFrom(readMethod.getReturnType())) {
try {
final Object propertyValue = readMethod.invoke(instance);
returnValue = requiredType.cast(propertyValue);
} catch (final Exception e) {
e.printStackTrace(); // unable to invoke readMethod
}
}
} catch (final IntrospectionException e) {
throw new IllegalArgumentException("Property '" + propertyName + "' is NOT defined in "
+ instance.getClass().getName() + "!", e);
}
return returnValue;
}
DateValidator.java
public class DateValidator {
/**
* The Enum DateComparisonMode.
*
* Determins which Type of validation is used
*/
public enum DateComparisonMode {
/** the given Date must be BEFORE the referenced Date */
BEFORE,
/** the given Date must be BEFORE_OR_EQUAL the referenced Date */
BEFORE_OR_EQUAL,
/** the given Date must be EQUAL the referenced Date */
EQUAL,
/** the given Date must be AFTER_OR_EQUAL the referenced Date */
AFTER_OR_EQUAL,
/** the given Date must be AFTER the referenced Date */
AFTER;
}
/**
* Compare 2 Date Values based on a given Comparison Mode.
*
* #param baseDate the base date
* #param valuationDate the valuation date
* #param comparisonMode the comparison mode
* #return true, if is valid
*/
public static boolean isValid(final Date baseDate, final Date valuationDate, final DateComparisonMode comparisonMode) {
// Timevalue of both dates will be set to 00:00:0000
final Date compValuationDate = DateValidator.convertDate(valuationDate);
final Date compBaseDate = DateValidator.convertDate(baseDate);
// compare the values
final int result = compValuationDate.compareTo(compBaseDate);
// match the result to the comparisonMode and return true
// if rule is fulfilled
switch (result) {
case -1:
if (comparisonMode == DateComparisonMode.BEFORE) {
return true;
}
if (comparisonMode == DateComparisonMode.BEFORE_OR_EQUAL) {
return true;
}
break;
case 0:
if (comparisonMode == DateComparisonMode.BEFORE_OR_EQUAL) {
return true;
}
if (comparisonMode == DateComparisonMode.EQUAL) {
return true;
}
if (comparisonMode == DateComparisonMode.AFTER_OR_EQUAL) {
return true;
}
break;
case 1:
if (comparisonMode == DateComparisonMode.AFTER) {
return true;
}
if (comparisonMode == DateComparisonMode.AFTER_OR_EQUAL) {
return true;
}
break;
default:
return false; // should not happen....
}
return false;
}
/**
* Convert date.
*
* sets the time Value of a given Date filed to 00:00:0000
*
* #param t the t
* #return the date
*/
private static Date convertDate(final Date t) {
final Calendar calendar = Calendar.getInstance();
calendar.setTime(t);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return (calendar.getTime());
}
Especially the property retrieval was taken from this post question
JSF 2.0 doesn't call class level validation constraints.
From JSF validation:
JSF 2 provides built-in integration with JSR-303 constraints. When you
are using bean validation in your application, JSF automatically uses
the constraints for beans that are referenced by UIInput values.
You have to call it manually, or you can try Seam Faces which has an extension <f:validateBean>
Related
I used soapUi to generate a Java Pojo from a WSDL, one of the generated class looks like the following below FACValidatyRequest class
package com.innovectives.octopus.gt.bank.agency.common.dto;
import javax.xml.stream.XMLStreamException;
import org.apache.axis2.databinding.ADBException;
/**
* FacValidityRequest bean class
*/
#SuppressWarnings({"unchecked",
"unused"
})
public class FacValidityRequest implements org.apache.axis2.databinding.ADBBean {
/* This type was generated from the piece of schema that had
name = FacValidityRequest
Namespace URI = http://tempuri.org/
Namespace Prefix = ns1
*/
/**
* field for FACCode
*/
protected java.lang.String localFACCode;
/* This tracker boolean wil be used to detect whether the user called the set method
* for this attribute. It will be used to determine whether to include this field
* in the serialized XML
*/
protected boolean localFACCodeTracker = false;
/**
* field for MobileNumber
*/
protected java.lang.String localMobileNumber;
/* This tracker boolean wil be used to detect whether the user called the set method
* for this attribute. It will be used to determine whether to include this field
* in the serialized XML
*/
protected boolean localMobileNumberTracker = false;
/**
* field for UniqueId
*/
protected java.lang.String localUniqueId;
/* This tracker boolean wil be used to detect whether the user called the set method
* for this attribute. It will be used to determine whether to include this field
* in the serialized XML
*/
protected boolean localUniqueIdTracker = false;
/**
* field for Hash
*/
protected java.lang.String localHash;
/* This tracker boolean wil be used to detect whether the user called the set method
* for this attribute. It will be used to determine whether to include this field
* in the serialized XML
*/
protected boolean localHashTracker = false;
public boolean isFACCodeSpecified() {
return localFACCodeTracker;
}
/**
* Auto generated getter method
* #return java.lang.String
*/
public java.lang.String getFACCode() {
return localFACCode;
}
/**
* Auto generated setter method
* #param param FACCode
*/
public void setFACCode(java.lang.String param) {
localFACCodeTracker = param != null;
this.localFACCode = param;
}
public boolean isMobileNumberSpecified() {
return localMobileNumberTracker;
}
/**
* Auto generated getter method
* #return java.lang.String
*/
public java.lang.String getMobileNumber() {
return localMobileNumber;
}
/**
* Auto generated setter method
* #param param MobileNumber
*/
public void setMobileNumber(java.lang.String param) {
localMobileNumberTracker = param != null;
this.localMobileNumber = param;
}
public boolean isUniqueIdSpecified() {
return localUniqueIdTracker;
}
/**
* Auto generated getter method
* #return java.lang.String
*/
public java.lang.String getUniqueId() {
return localUniqueId;
}
/**
* Auto generated setter method
* #param param UniqueId
*/
public void setUniqueId(java.lang.String param) {
localUniqueIdTracker = param != null;
this.localUniqueId = param;
}
public boolean isHashSpecified() {
return localHashTracker;
}
/**
* Auto generated getter method
* #return java.lang.String
*/
public java.lang.String getHash() {
return localHash;
}
/**
* Auto generated setter method
* #param param Hash
*/
public void setHash(java.lang.String param) {
localHashTracker = param != null;
this.localHash = param;
}
/**
*
* #param parentQName
* #param factory
* #return org.apache.axiom.om.OMElement
* #throws org.apache.axis2.databinding.ADBException
*/
#Override
public org.apache.axiom.om.OMElement getOMElement(
final javax.xml.namespace.QName parentQName,
final org.apache.axiom.om.OMFactory factory)
throws org.apache.axis2.databinding.ADBException {
return factory.createOMElement(new org.apache.axis2.databinding.ADBDataSource(
this, parentQName));
}
/**
*
* #param parentQName
* #param xmlWriter
* #throws XMLStreamException
* #throws ADBException
*/
#Override
public void serialize(final javax.xml.namespace.QName parentQName,
javax.xml.stream.XMLStreamWriter xmlWriter)
throws javax.xml.stream.XMLStreamException,
org.apache.axis2.databinding.ADBException {
serialize(parentQName, xmlWriter, false);
}
/**
*
* #param parentQName
* #param xmlWriter
* #param serializeType
* #throws XMLStreamException
* #throws ADBException
*/
#Override
public void serialize(final javax.xml.namespace.QName parentQName,
javax.xml.stream.XMLStreamWriter xmlWriter, boolean serializeType)
throws javax.xml.stream.XMLStreamException,
org.apache.axis2.databinding.ADBException {
java.lang.String prefix = null;
java.lang.String namespace = null;
prefix = parentQName.getPrefix();
namespace = parentQName.getNamespaceURI();
writeStartElement(prefix, namespace, parentQName.getLocalPart(),
xmlWriter);
if (serializeType) {
java.lang.String namespacePrefix = registerPrefix(xmlWriter,
"http://tempuri.org/");
if ((namespacePrefix != null) &&
(namespacePrefix.trim().length() > 0)) {
writeAttribute("xsi",
"http://www.w3.org/2001/XMLSchema-instance", "type",
namespacePrefix + ":FacValidityRequest", xmlWriter);
} else {
writeAttribute("xsi",
"http://www.w3.org/2001/XMLSchema-instance", "type",
"FacValidityRequest", xmlWriter);
}
}
if (localFACCodeTracker) {
namespace = "http://tempuri.org/";
writeStartElement(null, namespace, "FACCode", xmlWriter);
if (localFACCode == null) {
// write the nil attribute
throw new org.apache.axis2.databinding.ADBException(
"FACCode cannot be null!!");
} else {
xmlWriter.writeCharacters(localFACCode);
}
xmlWriter.writeEndElement();
}
if (localMobileNumberTracker) {
namespace = "http://tempuri.org/";
writeStartElement(null, namespace, "MobileNumber", xmlWriter);
if (localMobileNumber == null) {
// write the nil attribute
throw new org.apache.axis2.databinding.ADBException(
"MobileNumber cannot be null!!");
} else {
xmlWriter.writeCharacters(localMobileNumber);
}
xmlWriter.writeEndElement();
}
if (localUniqueIdTracker) {
namespace = "http://tempuri.org/";
writeStartElement(null, namespace, "UniqueId", xmlWriter);
if (localUniqueId == null) {
// write the nil attribute
throw new org.apache.axis2.databinding.ADBException(
"UniqueId cannot be null!!");
} else {
xmlWriter.writeCharacters(localUniqueId);
}
xmlWriter.writeEndElement();
}
if (localHashTracker) {
namespace = "http://tempuri.org/";
writeStartElement(null, namespace, "Hash", xmlWriter);
if (localHash == null) {
// write the nil attribute
throw new org.apache.axis2.databinding.ADBException(
"Hash cannot be null!!");
} else {
xmlWriter.writeCharacters(localHash);
}
xmlWriter.writeEndElement();
}
xmlWriter.writeEndElement();
}
private static java.lang.String generatePrefix(java.lang.String namespace) {
if (namespace.equals("http://tempuri.org/")) {
return "ns1";
}
return org.apache.axis2.databinding.utils.BeanUtil.getUniquePrefix();
}
/**
* Utility method to write an element start tag.
*/
private void writeStartElement(java.lang.String prefix,
java.lang.String namespace, java.lang.String localPart,
javax.xml.stream.XMLStreamWriter xmlWriter)
throws javax.xml.stream.XMLStreamException {
java.lang.String writerPrefix = xmlWriter.getPrefix(namespace);
if (writerPrefix != null) {
xmlWriter.writeStartElement(writerPrefix, localPart, namespace);
} else {
if (namespace.length() == 0) {
prefix = "";
} else if (prefix == null) {
prefix = generatePrefix(namespace);
}
xmlWriter.writeStartElement(prefix, localPart, namespace);
xmlWriter.writeNamespace(prefix, namespace);
xmlWriter.setPrefix(prefix, namespace);
}
}
/**
* Util method to write an attribute with the ns prefix
*/
private void writeAttribute(java.lang.String prefix,
java.lang.String namespace, java.lang.String attName,
java.lang.String attValue, javax.xml.stream.XMLStreamWriter xmlWriter)
throws javax.xml.stream.XMLStreamException {
java.lang.String writerPrefix = xmlWriter.getPrefix(namespace);
if (writerPrefix != null) {
xmlWriter.writeAttribute(writerPrefix, namespace, attName, attValue);
} else {
xmlWriter.writeNamespace(prefix, namespace);
xmlWriter.setPrefix(prefix, namespace);
xmlWriter.writeAttribute(prefix, namespace, attName, attValue);
}
}
/**
* Util method to write an attribute without the ns prefix
*/
private void writeAttribute(java.lang.String namespace,
java.lang.String attName, java.lang.String attValue,
javax.xml.stream.XMLStreamWriter xmlWriter)
throws javax.xml.stream.XMLStreamException {
if (namespace.equals("")) {
xmlWriter.writeAttribute(attName, attValue);
} else {
xmlWriter.writeAttribute(registerPrefix(xmlWriter, namespace),
namespace, attName, attValue);
}
}
/**
* Util method to write an attribute without the ns prefix
*/
private void writeQNameAttribute(java.lang.String namespace,
java.lang.String attName, javax.xml.namespace.QName qname,
javax.xml.stream.XMLStreamWriter xmlWriter)
throws javax.xml.stream.XMLStreamException {
java.lang.String attributeNamespace = qname.getNamespaceURI();
java.lang.String attributePrefix = xmlWriter.getPrefix(attributeNamespace);
if (attributePrefix == null) {
attributePrefix = registerPrefix(xmlWriter, attributeNamespace);
}
java.lang.String attributeValue;
if (attributePrefix.trim().length() > 0) {
attributeValue = attributePrefix + ":" + qname.getLocalPart();
} else {
attributeValue = qname.getLocalPart();
}
if (namespace.equals("")) {
xmlWriter.writeAttribute(attName, attributeValue);
} else {
registerPrefix(xmlWriter, namespace);
xmlWriter.writeAttribute(attributePrefix, namespace, attName,
attributeValue);
}
}
/**
* method to handle Qnames
*/
private void writeQName(javax.xml.namespace.QName qname,
javax.xml.stream.XMLStreamWriter xmlWriter)
throws javax.xml.stream.XMLStreamException {
java.lang.String namespaceURI = qname.getNamespaceURI();
if (namespaceURI != null) {
java.lang.String prefix = xmlWriter.getPrefix(namespaceURI);
if (prefix == null) {
prefix = generatePrefix(namespaceURI);
xmlWriter.writeNamespace(prefix, namespaceURI);
xmlWriter.setPrefix(prefix, namespaceURI);
}
if (prefix.trim().length() > 0) {
xmlWriter.writeCharacters(prefix + ":" +
org.apache.axis2.databinding.utils.ConverterUtil.convertToString(
qname));
} else {
// i.e this is the default namespace
xmlWriter.writeCharacters(org.apache.axis2.databinding.utils.ConverterUtil.convertToString(
qname));
}
} else {
xmlWriter.writeCharacters(org.apache.axis2.databinding.utils.ConverterUtil.convertToString(
qname));
}
}
private void writeQNames(javax.xml.namespace.QName[] qnames,
javax.xml.stream.XMLStreamWriter xmlWriter)
throws javax.xml.stream.XMLStreamException {
if (qnames != null) {
// we have to store this data until last moment since it is not possible to write any
// namespace data after writing the charactor data
StringBuilder stringToWrite = new StringBuilder();
java.lang.String namespaceURI = null;
java.lang.String prefix = null;
for (int i = 0; i < qnames.length; i++) {
if (i > 0) {
stringToWrite.append(" ");
}
namespaceURI = qnames[i].getNamespaceURI();
if (namespaceURI != null) {
prefix = xmlWriter.getPrefix(namespaceURI);
if ((prefix == null) || (prefix.length() == 0)) {
prefix = generatePrefix(namespaceURI);
xmlWriter.writeNamespace(prefix, namespaceURI);
xmlWriter.setPrefix(prefix, namespaceURI);
}
if (prefix.trim().length() > 0) {
stringToWrite.append(prefix).append(":")
.append(org.apache.axis2.databinding.utils.ConverterUtil.convertToString(
qnames[i]));
} else {
stringToWrite.append(org.apache.axis2.databinding.utils.ConverterUtil.convertToString(
qnames[i]));
}
} else {
stringToWrite.append(org.apache.axis2.databinding.utils.ConverterUtil.convertToString(
qnames[i]));
}
}
xmlWriter.writeCharacters(stringToWrite.toString());
}
}
/**
* Register a namespace prefix
*/
private java.lang.String registerPrefix(
javax.xml.stream.XMLStreamWriter xmlWriter, java.lang.String namespace)
throws javax.xml.stream.XMLStreamException {
java.lang.String prefix = xmlWriter.getPrefix(namespace);
if (prefix == null) {
prefix = generatePrefix(namespace);
javax.xml.namespace.NamespaceContext nsContext = xmlWriter.getNamespaceContext();
while (true) {
java.lang.String uri = nsContext.getNamespaceURI(prefix);
if ((uri == null) || (uri.length() == 0)) {
break;
}
prefix = org.apache.axis2.databinding.utils.BeanUtil.getUniquePrefix();
}
xmlWriter.writeNamespace(prefix, namespace);
xmlWriter.setPrefix(prefix, namespace);
}
return prefix;
}
/**
* Factory class that keeps the parse method
*/
public static class Factory {
private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(Factory.class);
/**
* static method to create the object
* Precondition: If this object is an element, the current or next start element starts this object and any intervening reader events are ignorable
* If this object is not an element, it is a complex type and the reader is at the event just after the outer start element
* Postcondition: If this object is an element, the reader is positioned at its end element
* If this object is a complex type, the reader is positioned at the end element of its outer element
* #param reader
* #return
* #throws java.lang.Exception
*/
public static FacValidityRequest parse(
javax.xml.stream.XMLStreamReader reader) throws java.lang.Exception {
FacValidityRequest object = new FacValidityRequest();
int event;
javax.xml.namespace.QName currentQName = null;
java.lang.String nillableValue = null;
java.lang.String prefix = "";
java.lang.String namespaceuri = "";
try {
while (!reader.isStartElement() && !reader.isEndElement())
reader.next();
currentQName = reader.getName();
if (reader.getAttributeValue(
"http://www.w3.org/2001/XMLSchema-instance", "type") != null) {
java.lang.String fullTypeName = reader.getAttributeValue("http://www.w3.org/2001/XMLSchema-instance",
"type");
if (fullTypeName != null) {
java.lang.String nsPrefix = null;
if (fullTypeName.indexOf(":") > -1) {
nsPrefix = fullTypeName.substring(0,
fullTypeName.indexOf(":"));
}
nsPrefix = (nsPrefix == null) ? "" : nsPrefix;
java.lang.String type = fullTypeName.substring(fullTypeName.indexOf(
":") + 1);
if (!"FacValidityRequest".equals(type)) {
//find namespace for the prefix
java.lang.String nsUri = reader.getNamespaceContext()
.getNamespaceURI(nsPrefix);
return (FacValidityRequest) ExtensionMapper.getTypeObject(nsUri,
type, reader);
}
}
}
// Note all attributes that were handled. Used to differ normal attributes
// from anyAttributes.
java.util.Vector handledAttributes = new java.util.Vector();
reader.next();
while (!reader.isStartElement() && !reader.isEndElement())
reader.next();
if (reader.isStartElement() &&
new javax.xml.namespace.QName("http://tempuri.org/",
"FACCode").equals(reader.getName())) {
nillableValue = reader.getAttributeValue("http://www.w3.org/2001/XMLSchema-instance",
"nil");
if ("true".equals(nillableValue) ||
"1".equals(nillableValue)) {
throw new org.apache.axis2.databinding.ADBException(
"The element: " + "FACCode" + " cannot be null");
}
java.lang.String content = reader.getElementText();
object.setFACCode(org.apache.axis2.databinding.utils.ConverterUtil.convertToString(
content));
reader.next();
} // End of if for expected property start element
else {
}
while (!reader.isStartElement() && !reader.isEndElement())
reader.next();
if (reader.isStartElement() &&
new javax.xml.namespace.QName("http://tempuri.org/",
"MobileNumber").equals(reader.getName())) {
nillableValue = reader.getAttributeValue("http://www.w3.org/2001/XMLSchema-instance",
"nil");
if ("true".equals(nillableValue) ||
"1".equals(nillableValue)) {
throw new org.apache.axis2.databinding.ADBException(
"The element: " + "MobileNumber" +
" cannot be null");
}
java.lang.String content = reader.getElementText();
object.setMobileNumber(org.apache.axis2.databinding.utils.ConverterUtil.convertToString(
content));
reader.next();
} // End of if for expected property start element
else {
}
while (!reader.isStartElement() && !reader.isEndElement())
reader.next();
if (reader.isStartElement() &&
new javax.xml.namespace.QName("http://tempuri.org/",
"UniqueId").equals(reader.getName())) {
nillableValue = reader.getAttributeValue("http://www.w3.org/2001/XMLSchema-instance",
"nil");
if ("true".equals(nillableValue) ||
"1".equals(nillableValue)) {
throw new org.apache.axis2.databinding.ADBException(
"The element: " + "UniqueId" + " cannot be null");
}
java.lang.String content = reader.getElementText();
object.setUniqueId(org.apache.axis2.databinding.utils.ConverterUtil.convertToString(
content));
reader.next();
} // End of if for expected property start element
else {
}
while (!reader.isStartElement() && !reader.isEndElement())
reader.next();
if (reader.isStartElement() &&
new javax.xml.namespace.QName("http://tempuri.org/",
"Hash").equals(reader.getName())) {
nillableValue = reader.getAttributeValue("http://www.w3.org/2001/XMLSchema-instance",
"nil");
if ("true".equals(nillableValue) ||
"1".equals(nillableValue)) {
throw new org.apache.axis2.databinding.ADBException(
"The element: " + "Hash" + " cannot be null");
}
java.lang.String content = reader.getElementText();
object.setHash(org.apache.axis2.databinding.utils.ConverterUtil.convertToString(
content));
reader.next();
} // End of if for expected property start element
else {
}
while (!reader.isStartElement() && !reader.isEndElement())
reader.next();
if (reader.isStartElement()) {
// 2 - A start element we are not expecting indicates a trailing invalid property
throw new org.apache.axis2.databinding.ADBException(
"Unexpected subelement " + reader.getName());
}
} catch (javax.xml.stream.XMLStreamException e) {
throw new java.lang.Exception(e);
}
return object;
}
} //end of factory class
}
I tried to use the POJO and set its values as I have done below but I can not view the String representation of my POJO when I print it out to console using system.out.println I can not also convert my POJO to string to be sent across the internet, rather it gives me the following below which I guess is an address in memory but I want the string representation
com.innovectives.octopus.gt.bank.agency.common.dto.FacValidityRequest#2d9b42e2
FacValidityRequest commonGTRequest = new FacValidityRequest();
commonGTRequest.setFACCode("1095780292");
commonGTRequest.setMobileNumber("08036952110");
commonGTRequest.setUniqueId(OctopusHelper.randomUUIDString());
commonGTRequest.setHash("hashing");
JAXBContext context = JAXBContext.newInstance(FacValidityRequest.class);
System.out.println("data = "+ ConvertXmlToString(commonGTRequest, context));
exchange.getIn(FacValidityRequest.class);
exchange.getIn().setBody(commonGTRequest);
LOG.info("end convertFacValidationRequest...\n" + exchange.getIn().getBody(String.class));
SAMPLE REQUEST
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:tem="http://tempuri.org/">
<soap:Header/>
<soap:Body>
<tem:FACValidityRequest>
<!--Optional:-->
<tem:facreq>
<!--Optional:-->
<tem:FACCode>?</tem:FACCode>
<!--Optional:-->
<tem:MobileNumber>?</tem:MobileNumber>
<!--Optional:-->
<tem:UniqueId>?</tem:UniqueId>
<!--Optional:-->
<tem:Hash>?</tem:Hash>
</tem:facreq>
</tem:FACValidityRequest>
</soap:Body>
</soap:Envelope>
How do I achieve this, with the generated POJO above.
What you get is an output of default Java Object.toString() implementation and it is correct - your class does not override toString().
So, either check Axis2/SoapUI documentation about is there a way to generate toString() method or (if not)
depends on how do you want to see your object String representation you can:
override toString() after class generated
create some utility to convert your object to String
simplest way is to use Apache BeanUtils.describe(Object obj) method
but if you want see actual XML as string you need to use one of serialize methods generated for you by Axis2.
something like:
// use ByteArrayOutputStream as example
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
XMLStreamWriter xmlWriter = XMLStreamWriterFactory.create(outStream);
// fake line !!! check Axis2 documentation what you need to pass as Parent QName to Serialize an object
javax.xml.namespace.QName parentQName = new javax.xml.namespace.QName("http://tempuri.org/","FacValidityRequest", "ns1");
// This is a main point to get a XML String out of POJO
myFacValidityRequestObject.serialize(parentQName , xmlWriter);
System.out.println(new String(outStream.toByteArray()));
xmlWriter.close();
You need just find out what actual Parent QName parameter must be there (in my example it is just a fake one)
This is my code:
public class Client
{
protected int cod;
protected String name;
public void setCod(int cod) throws Exception
{
if(cod==null)
throw new Exception("Invalid code!");
this.cod = cod;
}
public int getCod()
{
return this.cod;
}
public void setName(String name) throws Exception
{
if(name==null || name.equals("")
throw new Exception("Invalid name!");
this.name = name;
}
public String getName()
{
return this.name;
}
public Client(int cod, String name) throws Exception
{
this.setCod(cod);
this.setName(name);
}
public boolean equals(Object obj)
{
if(this==obj)
return true;
if(obj==null)
return false;
if(!(obj instanceof Client))
return false;
Client client = (Client)obj;
if(this.cod!=client.cod)
return false;
if(this.name!=client.name)
return false;
return true;
}
public String toString()
{
return "Code: " + this.cod + "\n" +
"Name: " + this.name;
}
public int hashCode()
{
int ret = 444;
ret += ret*7 + new Integer (this.cod).hashCode();
ret += ret*7 + (this.name).hashCode();
return ret;
}
public Object clone()
{
Client ret = null;
try
{
ret = new Client(this);
}
catch(Exception error)
{
// this is never null
}
return ret;
}
public Client(Client model) throws Exception
{
if(model==null)
throw new Exception("Inexistent model!");
this.cod = model.cod;
this.name = model.name;
}
}
I know that, to make a comment, you'll have to put "//" or " /* " and " */ ". But how can I comment following the JAVADOC rule?
If you know how, can you copy my code and put it in your answer, with the JAVADOC? Thanks :)
And please tell me, what is a JAVADOC, and what is it for? Is there any simple way to make it?
Javadoc is a kind of comment that you use in your program, to organize it, to make the program more friendly and to create a page HTML with everything you commented, like this:
So, to create a javadoc, you'll have top put /** in place of /*.
There is types of commands that you need to know when you're creating the javadoc.
#author - who created the program
#throws - for exceptions
#param - the method parameters
#return - what the method returns
So, your code with javadoc will be like this:
/**
* #author IncredibleCoding
*/
public class Client
{
protected int cod;
protected String name;
/**
* instance the code passed
*/
public void setCod(int cod) throws Exception
{
if(cod==null)
throw new Exception("Invalid code!");
this.cod = cod;
}
/**
* #returns the code
*/
public int getCod()
{
return this.cod;
}
/**
* instance the name passed
* #param name, that is the name passed
* #throws Exception, if the name is in invalid format
*/
public void setName(String name) throws Exception
{
if(name==null || name.equals("")
throw new Exception("Invalid name!");
this.name = name;
}
/**
* #returns the name
*/
public String getName()
{
return this.name;
}
/**
* the constructor
* #param cod, that is the code passed
* #param name, that is the name passed
*/
public Client(int cod, String name) throws Exception
{
this.setCod(cod);
this.setName(name);
}
/**
* #param obj, that is the object that will be compared
* #returns true if the object is equal to this, false if the object isn't equal
*/
public boolean equals(Object obj)
{
if(this==obj)
return true;
if(obj==null)
return false;
if(!(obj instanceof Client))
return false;
Client client = (Client)obj;
if(this.cod!=client.cod)
return false;
if(this.name!=client.name)
return false;
return true;
}
/**
* returns the formatted variable like String
*/
public String toString()
{
return "Code: " + this.cod + "\n" +
"Name: " + this.name;
}
/**
* returns the hashCode of a variable
*/
public int hashCode()
{
int ret = 444;
ret += ret*7 + new Integer (this.cod).hashCode();
ret += ret*7 + (this.name).hashCode();
return ret;
}
/**
* clone the object
*/
public Object clone()
{
Client ret = null;
try
{
ret = new Client(this);
}
catch(Exception error)
{
// this is never null
}
return ret;
}
/**
* "copy" the variables
* #param model, that is the object that will be copied
* #throws Exception, if the model is inexistent
*/
public Client(Client model) throws Exception
{
if(model==null)
throw new Exception("Inexistent model!");
this.cod = model.cod;
this.name = model.name;
}
}
You should consider take a look in this ORACLE's page, this will help you too:
https://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html
For an application I'm developing, a lot of older clients with larger fingers and poor eyesight need the selection arrows and Date/Year labels to be larger on the DatePicker Pop-Up.
In the documentation of the DatePicker class, there are methods described for modifying the DateCells within the calendar itself, but nothing describes or elaborates on the construction of the popup any further. (At least, the code is not self-documented plainly enough for my entry-level knowledge of Java development to grasp any hints)
My implementation ends up looking like this
Sometimes when I open and close the calendar, the size of the font and buttons in the Month/Year controls fluctuate, but I have no idea how or why. I assume some CSS may be tampering with it, but I have no idea why it would sometimes work and sometimes not. CSS' true nature has always escaped me.
I know it [DatePicker] is based on a ComboBox, but I have absolutely zero idea how it is constructed and fully implemented, much less how to modify very specific elements in it.
Is there a method I can call/Override, or a parameter I can modify in-line to style these properly? Also, could there be a combination of classes and elements I can call in CSS to style these to avoid having to outright modify DatePicker itself as described above?
Here is my implementation:
#FXML private DatePicker dPicker;
final Callback<DatePicker, DateCell> dayCellFactory =
new Callback<DatePicker, DateCell>() {
#Override
public DateCell call(final DatePicker datePicker) {
return new DateCell() {
#Override
public void updateItem(LocalDate item, boolean empty) {
super.updateItem(item, empty);
setMinSize(100,100);
setStyle("-fx-font-size:50px;-fx-font-weight:bold;");
}
};
}
};
dPicker.setDayCellFactory(dayCellFactory);
...and here is DataPicker.java:
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package javafx.scene.control;
// editor and converter code in sync with ComboBox 4858:e60e9a5396e6
import java.time.LocalDate;
import java.time.DateTimeException;
import java.time.chrono.Chronology;
import java.time.chrono.ChronoLocalDate;
import java.time.chrono.IsoChronology;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DecimalStyle;
import java.time.format.FormatStyle;
import java.time.temporal.TemporalAccessor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import com.sun.javafx.scene.control.skin.ComboBoxListViewSkin;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.beans.property.SimpleObjectProperty;
import javafx.css.CssMetaData;
import javafx.css.Styleable;
import javafx.css.StyleableBooleanProperty;
import javafx.css.StyleableProperty;
import javafx.util.Callback;
import javafx.util.StringConverter;
import com.sun.javafx.css.converters.BooleanConverter;
import com.sun.javafx.scene.control.skin.DatePickerSkin;
import com.sun.javafx.scene.control.skin.resources.ControlResources;
/**
* The DatePicker control allows the user to enter a date as text or
* to select a date from a calendar popup. The calendar is based on
* either the standard ISO-8601 chronology or any of the other
* chronology classes defined in the java.time.chrono package.
*
* <p>The {#link #valueProperty() value} property represents the
* currently selected {#link java.time.LocalDate}. An initial date can
* be set via the {#link #DatePicker(java.time.LocalDate) constructor}
* or by calling {#link #setValue(java.time.LocalDate) setValue()}. The
* default value is null.
*
* <pre><code>
* final DatePicker datePicker = new DatePicker();
* datePicker.setOnAction(new EventHandler() {
* public void handle(Event t) {
* LocalDate date = datePicker.getValue();
* System.err.println("Selected date: " + date);
* }
* });
* </code></pre>
*
* The {#link #chronologyProperty() chronology} property specifies a
* calendar system to be used for parsing, displaying, and choosing
* dates.
* The {#link #valueProperty() value} property is always defined in
* the ISO calendar system, however, so applications based on a
* different chronology may use the conversion methods provided in the
* {#link java.time.chrono.Chronology} API to get or set the
* corresponding {#link java.time.chrono.ChronoLocalDate} value. For
* example:
*
* <pre><code>
* LocalDate isoDate = datePicker.getValue();
* ChronoLocalDate chronoDate =
* ((isoDate != null) ? datePicker.getChronology().date(isoDate) : null);
* System.err.println("Selected date: " + chronoDate);
* </code></pre>
*
*
* #since JavaFX 8.0
*/
public class DatePicker extends ComboBoxBase<LocalDate> {
private LocalDate lastValidDate = null;
private Chronology lastValidChronology = IsoChronology.INSTANCE;
/**
* Creates a default DatePicker instance with a <code>null</code> date value set.
*/
public DatePicker() {
this(null);
valueProperty().addListener(new InvalidationListener() {
#Override public void invalidated(Observable observable) {
LocalDate date = getValue();
Chronology chrono = getChronology();
if (validateDate(chrono, date)) {
lastValidDate = date;
} else {
System.err.println("Restoring value to " +
((lastValidDate == null) ? "null" : getConverter().toString(lastValidDate)));
setValue(lastValidDate);
}
}
});
chronologyProperty().addListener(new InvalidationListener() {
#Override public void invalidated(Observable observable) {
LocalDate date = getValue();
Chronology chrono = getChronology();
if (validateDate(chrono, date)) {
lastValidChronology = chrono;
} else {
System.err.println("Restoring value to " + lastValidChronology);
setChronology(lastValidChronology);
}
}
});
}
private boolean validateDate(Chronology chrono, LocalDate date) {
try {
if (date != null) {
chrono.date(date);
}
return true;
} catch (DateTimeException ex) {
System.err.println(ex);
return false;
}
}
/**
* Creates a DatePicker instance and sets the
* {#link #valueProperty() value} to the given date.
*
* #param localDate to be set as the currently selected date in the DatePicker. Can be null.
*/
public DatePicker(LocalDate localDate) {
setValue(localDate);
getStyleClass().add(DEFAULT_STYLE_CLASS);
setEditable(true);
}
/***************************************************************************
* *
* Properties *
* *
**************************************************************************/
/**
* A custom cell factory can be provided to customize individual
* day cells in the DatePicker popup. Refer to {#link DateCell}
* and {#link Cell} for more information on cell factories.
* Example:
*
* <pre><code>
* final Callback<DatePicker, DateCell> dayCellFactory = new Callback<DatePicker, DateCell>() {
* public DateCell call(final DatePicker datePicker) {
* return new DateCell() {
* #Override public void updateItem(LocalDate item, boolean empty) {
* super.updateItem(item, empty);
*
* if (MonthDay.from(item).equals(MonthDay.of(9, 25))) {
* setTooltip(new Tooltip("Happy Birthday!"));
* setStyle("-fx-background-color: #ff4444;");
* }
* if (item.equals(LocalDate.now().plusDays(1))) {
* // Tomorrow is too soon.
* setDisable(true);
* }
* }
* };
* }
* };
* datePicker.setDayCellFactory(dayCellFactory);
* </code></pre>
*
* #defaultValue null
*/
private ObjectProperty<Callback<DatePicker, DateCell>> dayCellFactory;
public final void setDayCellFactory(Callback<DatePicker, DateCell> value) {
dayCellFactoryProperty().set(value);
}
public final Callback<DatePicker, DateCell> getDayCellFactory() {
return (dayCellFactory != null) ? dayCellFactory.get() : null;
}
public final ObjectProperty<Callback<DatePicker, DateCell>> dayCellFactoryProperty() {
if (dayCellFactory == null) {
dayCellFactory = new SimpleObjectProperty<Callback<DatePicker, DateCell>>(this, "dayCellFactory");
}
return dayCellFactory;
}
/**
* The calendar system used for parsing, displaying, and choosing
* dates in the DatePicker control.
*
* <p>The default value is returned from a call to
* {#code Chronology.ofLocale(Locale.getDefault(Locale.Category.FORMAT))}.
* The default is usually {#link java.time.chrono.IsoChronology} unless
* provided explicitly in the {#link java.util.Locale} by use of a
* Locale calendar extension.
*
* Setting the value to <code>null</code> will restore the default
* chronology.
*/
public final ObjectProperty<Chronology> chronologyProperty() {
return chronology;
}
private ObjectProperty<Chronology> chronology =
new SimpleObjectProperty<Chronology>(this, "chronology", null);
public final Chronology getChronology() {
Chronology chrono = chronology.get();
if (chrono == null) {
try {
chrono = Chronology.ofLocale(Locale.getDefault(Locale.Category.FORMAT));
} catch (Exception ex) {
System.err.println(ex);
}
if (chrono == null) {
chrono = IsoChronology.INSTANCE;
}
//System.err.println(chrono);
}
return chrono;
}
public final void setChronology(Chronology value) {
chronology.setValue(value);
}
/**
* Whether the DatePicker popup should display a column showing
* week numbers.
*
* <p>The default value is specified in a resource bundle, and
* depends on the country of the current locale.
*/
public final BooleanProperty showWeekNumbersProperty() {
if (showWeekNumbers == null) {
String country = Locale.getDefault(Locale.Category.FORMAT).getCountry();
boolean localizedDefault =
(!country.isEmpty() &&
ControlResources.getNonTranslatableString("DatePicker.showWeekNumbers").contains(country));
showWeekNumbers = new StyleableBooleanProperty(localizedDefault) {
#Override public CssMetaData<DatePicker,Boolean> getCssMetaData() {
return StyleableProperties.SHOW_WEEK_NUMBERS;
}
#Override public Object getBean() {
return DatePicker.this;
}
#Override public String getName() {
return "showWeekNumbers";
}
};
}
return showWeekNumbers;
}
private BooleanProperty showWeekNumbers;
public final void setShowWeekNumbers(boolean value) {
showWeekNumbersProperty().setValue(value);
}
public final boolean isShowWeekNumbers() {
return showWeekNumbersProperty().getValue();
}
// --- string converter
/**
* Converts the input text to an object of type LocalDate and vice
* versa.
*
* <p>If not set by the application, the DatePicker skin class will
* set a converter based on a {#link java.time.DateTimeFormatter}
* for the current {#link java.util.Locale} and
* {#link #chronologyProperty() chronology}. This formatter is
* then used to parse and display the current date value.
*
* Setting the value to <code>null</code> will restore the default
* converter.
*
* <p>Example using an explicit formatter:
* <pre><code>
* datePicker.setConverter(new StringConverter<LocalDate>() {
* String pattern = "yyyy-MM-dd";
* DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(pattern);
*
* {
* datePicker.setPromptText(pattern.toLowerCase());
* }
*
* #Override public String toString(LocalDate date) {
* if (date != null) {
* return dateFormatter.format(date);
* } else {
* return "";
* }
* }
*
* #Override public LocalDate fromString(String string) {
* if (string != null && !string.isEmpty()) {
* return LocalDate.parse(string, dateFormatter);
* } else {
* return null;
* }
* }
* });
* </code></pre>
* <p>Example that wraps the default formatter and catches parse exceptions:
* <pre><code>
* final StringConverter<LocalDate> defaultConverter = datePicker.getConverter();
* datePicker.setConverter(new StringConverter<LocalDate>() {
* #Override public String toString(LocalDate value) {
* return defaultConverter.toString(value);
* }
*
* #Override public LocalDate fromString(String text) {
* try {
* return defaultConverter.fromString(text);
* } catch (DateTimeParseException ex) {
* System.err.println("HelloDatePicker: "+ex.getMessage());
* throw ex;
* }
* }
* });
* </code></pre>
*
* #see javafx.scene.control.ComboBox#converterProperty
*/
public final ObjectProperty<StringConverter<LocalDate>> converterProperty() { return converter; }
private ObjectProperty<StringConverter<LocalDate>> converter =
new SimpleObjectProperty<StringConverter<LocalDate>>(this, "converter", null);
public final void setConverter(StringConverter<LocalDate> value) { converterProperty().set(value); }
public final StringConverter<LocalDate> getConverter() {
StringConverter<LocalDate> converter = converterProperty().get();
if (converter != null) {
return converter;
} else {
return defaultConverter;
}
}
private StringConverter<LocalDate> defaultConverter = new StringConverter<LocalDate>() {
#Override public String toString(LocalDate value) {
if (value != null) {
Locale locale = Locale.getDefault(Locale.Category.FORMAT);
Chronology chrono = getChronology();
ChronoLocalDate cDate;
try {
cDate = chrono.date(value);
} catch (DateTimeException ex) {
System.err.println(ex);
chrono = IsoChronology.INSTANCE;
cDate = value;
}
DateTimeFormatter dateFormatter =
DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT)
.withLocale(locale)
.withChronology(chrono)
.withDecimalStyle(DecimalStyle.of(locale));
String pattern =
DateTimeFormatterBuilder.getLocalizedDateTimePattern(FormatStyle.SHORT,
null, chrono, locale);
if (pattern.contains("yy") && !pattern.contains("yyy")) {
// Modify pattern to show four-digit year, including leading zeros.
String newPattern = pattern.replace("yy", "yyyy");
//System.err.println("Fixing pattern ("+forParsing+"): "+pattern+" -> "+newPattern);
dateFormatter = DateTimeFormatter.ofPattern(newPattern)
.withDecimalStyle(DecimalStyle.of(locale));
}
return dateFormatter.format(cDate);
} else {
return "";
}
}
#Override public LocalDate fromString(String text) {
if (text != null && !text.isEmpty()) {
Locale locale = Locale.getDefault(Locale.Category.FORMAT);
Chronology chrono = getChronology();
String pattern =
DateTimeFormatterBuilder.getLocalizedDateTimePattern(FormatStyle.SHORT,
null, chrono, locale);
DateTimeFormatter df =
new DateTimeFormatterBuilder().parseLenient()
.appendPattern(pattern)
.toFormatter()
.withChronology(chrono)
.withDecimalStyle(DecimalStyle.of(locale));
TemporalAccessor temporal = df.parse(text);
ChronoLocalDate cDate = chrono.date(temporal);
return LocalDate.from(cDate);
}
return null;
}
};
// --- Editor
/**
* The editor for the DatePicker.
*
* #see javafx.scene.control.ComboBox#editorProperty
*/
private ReadOnlyObjectWrapper<TextField> editor;
public final TextField getEditor() {
return editorProperty().get();
}
public final ReadOnlyObjectProperty<TextField> editorProperty() {
if (editor == null) {
editor = new ReadOnlyObjectWrapper<TextField>(this, "editor");
editor.set(new ComboBoxListViewSkin.FakeFocusTextField());
}
return editor.getReadOnlyProperty();
}
/** {#inheritDoc} */
#Override protected Skin<?> createDefaultSkin() {
return new DatePickerSkin(this);
}
/***************************************************************************
* *
* Stylesheet Handling *
* *
**************************************************************************/
private static final String DEFAULT_STYLE_CLASS = "date-picker";
/**
* #treatAsPrivate implementation detail
*/
private static class StyleableProperties {
private static final String country =
Locale.getDefault(Locale.Category.FORMAT).getCountry();
private static final CssMetaData<DatePicker, Boolean> SHOW_WEEK_NUMBERS =
new CssMetaData<DatePicker, Boolean>("-fx-show-week-numbers",
BooleanConverter.getInstance(),
(!country.isEmpty() &&
ControlResources.getNonTranslatableString("DatePicker.showWeekNumbers").contains(country))) {
#Override public boolean isSettable(DatePicker n) {
return n.showWeekNumbers == null || !n.showWeekNumbers.isBound();
}
#Override public StyleableProperty<Boolean> getStyleableProperty(DatePicker n) {
return (StyleableProperty)n.showWeekNumbersProperty();
}
};
private static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES;
static {
final List<CssMetaData<? extends Styleable, ?>> styleables =
new ArrayList<CssMetaData<? extends Styleable, ?>>(Control.getClassCssMetaData());
Collections.addAll(styleables,
SHOW_WEEK_NUMBERS
);
STYLEABLES = Collections.unmodifiableList(styleables);
}
}
/**
* #return The CssMetaData associated with this class, which may include the
* CssMetaData of its super classes.
*/
public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() {
return StyleableProperties.STYLEABLES;
}
/**
* {#inheritDoc}
*/
#Override
public List<CssMetaData<? extends Styleable, ?>> getControlCssMetaData() {
return getClassCssMetaData();
}
}
...and thanks in advance for being patient and helping me out.
The best way to change appearance like this is to use an external CSS. You can refer to the source code for the default stylesheet to see how the defaults are defined: the interesting parts for the DatePicker are near the bottom (lines 2932 onwards at the time of writing).
You can change the font size for the entire control just by doing
.date-picker {
-fx-font-size: 18pt ;
}
That ends up looking a little cluttered, so adding a bit of padding around the day names helps. The arrows will automatically scale to fit, so they will increase size with the increased font size on the month and year labels.
Here's a complete example:
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.DatePicker;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class DatePickerExample extends Application {
#Override
public void start(Stage primaryStage) {
DatePicker datePicker = new DatePicker();
VBox root = new VBox(datePicker);
Scene scene = new Scene(root, 250, 150);
scene.getStylesheets().add("date-picker-readable.css");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
date-picker-readable.css:
.date-picker {
-fx-font-size: 18pt;
-fx-font-weight: bold ;
}
.date-picker .day-name-cell {
-fx-padding: 10px ;
}
I am developing an java application that accepts SOAP message. The body of the SOAP contains various documents. From time to time their number varies (depending on the version of the album).
For their analysis I am trying to apply a pattern Abstract Factory.
But my implementation, I ran into a problem:
IAlbumFactory albumFactory = AlbumFactory.buildDocument (Album.A_5_0_12);
The first parameter has I can point to any type of enum CustomDocument (although CustomDocument.DO1 only valid Du). And this error only shows up in RunTime
IDocumentEntity <Du, org.w3c.dom.Element> documentEntity =
albumFactory.getWorker (CustomDocument.DO1);
how to avoid it?
Some class:
public interface IDocumentEntity<T,E> {
T getReport(E e) throws JAXBException ;
}
public interface IAlbumFactory {
IDocumentEntity getWorker(CustomDocument document);
}
/**
* Class for convert document DO1 (album 5.0.12) from org.w3c.dom.Element to Du
* entity type
*
* #author uas
*/
public class DO1_5_0_12 implements IDocumentEntity<Du, org.w3c.dom.Element> {
protected DO1ReportInType unmarshall(org.w3c.dom.Element e) throws JAXBException {
DO1ReportInType resultType = null;
JAXBContext result = JAXBContextHelper_DO1.getJaxbContextInstance();
Unmarshaller u = result.createUnmarshaller();
Object c = u.unmarshal(e);
if (c instanceof JAXBElement) {
JAXBElement jaxbe = (JAXBElement) c;
resultType = (DO1ReportInType) JAXBIntrospector.getValue(jaxbe);
}
return resultType;
}
#Override
public Du getReport(org.w3c.dom.Element e) throws JAXBException {
DO1ReportInType dO1Report = unmarshall(e);
DO1ReportIn_JAXBtoORCL btoORCL = new DO1ReportIn_JAXBtoORCL(dO1Report);
return btoORCL.getReport();
}
}
Factory for Album 5_0_12.
public class AlbumFactory_5_0_12 implements IAlbumFactory {
/**
* Return documentWorker byn CustomDocument value
* #param customDocument
* #return throws IllegalArgumentException
*/
#Override
public IDocumentEntity getWorker(CustomDocument customDocument) {
IDocumentEntity doc = null;
switch (customDocument) {
case DO1:
doc = new DO1_5_0_12();
break;
case DO2:
doc = new DO2_5_0_12();
break;
default:
throw new IllegalArgumentException("For album 5.0.12 " + customDocument.DocName() + " not support");
}
return doc;
}
}
public class AlbumFactory {
private AlbumFactory() {
}
public static IAlbumFactory buildDocument(Album album) {
IAlbumFactory result = null;
switch (album) {
case A_5_0_12:
result = new AlbumFactory_5_0_12();
break;
default:
throw new IllegalArgumentException("This version " + album.AlbumName() + " is not support");
}
return result;
}
}
I've created a custom validator to validate dateTimefield.
My problem is that I can't add it to the
datetimefield variable
The method add(IValidator<? super Date>) in the type FormComponent<Date> is not applicable for the arguments (DateTimeFieldValidator)
This is the error I'm getting.
Is there any standard way to validate DateTimeField?
package validators;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import org.apache.wicket.extensions.yui.calendar.DateTimeField;
import org.apache.wicket.validation.IValidatable;
import org.apache.wicket.validation.IValidator;
import org.apache.wicket.validation.ValidationError;
public class DateTimeFieldValidator implements IValidator<DateTimeField> {
/**
*
*/
private static final long serialVersionUID = 2342344609244L;
public DateTimeFieldValidator() {
}
private void error(IValidatable<DateTimeField> validatable, String errorKey) {
ValidationError error = new ValidationError();
error.addMessageKey(getClass().getSimpleName() + "." + errorKey);
validatable.error(error);
}
public void validate(IValidatable<DateTimeField> validatable) {
DateTimeField dateTime = (DateTimeField) validatable.getValue();
if ( dateTime== null){
error(validatable, "invalid.datetime");
}
else{
if( dateTime.getHours()!=null){
if( dateTime.getHours()>12 || dateTime.getHours()<0){
error(validatable, "invalid.hour");
}
}
else{
error(validatable, "invalid.hour");
}
if(dateTime.getMinutes()!=null){
if( dateTime.getMinutes() > 60 ){
error(validatable, "invalid.hour");
}
}else {
error(validatable, "invalid.minutes");
}
if( dateTime.getDate() == null ){
error(validatable, "invalid.date");
}
}
}
boolean isLegalDate(String s) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.setLenient(false);
return sdf.parse(s, new ParsePosition(0)) != null;
}
}
This is how I'm adding the validator.
startDateTimeField.add(new DateTimeFieldValidator());
Your DateTimeFieldValidator must implement IValidator<Date> instead of IValidator<DateTimeField>
I end up validating the datetimefield following way ..
And find out the datetimefield( yui ) have built in validation - which actually take care of the all the basic validations.
All you have to do is put a XXX.properties file in the folder -
you can also add your own error key and message - like I used startDate.after.enddate
IFormValidator validator = new AbstractFormValidator() {
/**
*
*/
private static final long serialVersionUID = -3252346839511722L;
public FormComponent<?>[] getDependentFormComponents() {
return new FormComponent[] { startField, endField };
}
ValidationError error = new ValidationError();
public void validate(Form<?> form) {
Date startDate = (Date) startField.getConvertedInput();
if(endField.isEnabled()){
Date endDate = (Date) endField.getConvertedInput();
if (endDate.before(startDate)){
error.addMessageKey(getClass().getSimpleName() + "startDate.after.enddate");
startField.error(error);
}
}
}
};
logForm.add(validator );