[SYNCOPE-664] Merge from 1_2_X
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/496a02a5 Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/496a02a5 Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/496a02a5 Branch: refs/heads/master Commit: 496a02a51547f2ba4a48d54bee7a8a4de48df076 Parents: c910a7a b81cea7 Author: Francesco Chicchiriccò <[email protected]> Authored: Mon May 4 17:57:09 2015 +0200 Committer: Francesco Chicchiriccò <[email protected]> Committed: Mon May 4 17:57:09 2015 +0200 ---------------------------------------------------------------------- .../persistence/jpa/entity/AbstractPlainAttrValue.java | 13 +++++++++++-- core/persistence-jpa/src/test/resources/content.xml | 4 +++- 2 files changed, 14 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/syncope/blob/496a02a5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrValue.java ---------------------------------------------------------------------- diff --cc core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrValue.java index c3469b1,0000000..c6a3bd7 mode 100644,000000..100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrValue.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrValue.java @@@ -1,282 -1,0 +1,291 @@@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.persistence.jpa.entity; + +import java.util.Date; +import javax.persistence.Basic; +import javax.persistence.Lob; +import javax.persistence.MappedSuperclass; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.ArrayUtils; ++import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.builder.ReflectionToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import org.apache.syncope.common.lib.types.AttrSchemaType; +import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidPlainAttrValueException; +import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValidationException; +import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; +import org.apache.syncope.core.persistence.api.entity.PlainSchema; +import org.apache.syncope.core.misc.DataFormat; +import org.apache.syncope.core.persistence.jpa.validation.entity.PlainAttrValueCheck; +import org.apache.syncope.core.misc.security.Encryptor; + +@MappedSuperclass +@PlainAttrValueCheck +public abstract class AbstractPlainAttrValue extends AbstractEntity<Long> implements PlainAttrValue { + + private static final long serialVersionUID = -9141923816611244785L; + + private String stringValue; + + @Temporal(TemporalType.TIMESTAMP) + private Date dateValue; + + @Basic + @Min(0) + @Max(1) + private Integer booleanValue; + + private Long longValue; + + private Double doubleValue; + + @Lob + private byte[] binaryValue; + + @Override + public Boolean getBooleanValue() { + return booleanValue == null + ? null + : isBooleanAsInteger(booleanValue); + } + + @Override + public void setBooleanValue(final Boolean booleanValue) { + this.booleanValue = booleanValue == null + ? null + : getBooleanAsInteger(booleanValue); + } + + @Override + public Date getDateValue() { + return dateValue == null + ? null + : new Date(dateValue.getTime()); + } + + @Override + public void setDateValue(final Date dateValue) { + this.dateValue = dateValue == null + ? null + : new Date(dateValue.getTime()); + } + + @Override + public Double getDoubleValue() { + return doubleValue; + } + + @Override + public void setDoubleValue(final Double doubleValue) { + this.doubleValue = doubleValue; + } + + @Override + public Long getLongValue() { + return longValue; + } + + @Override + public void setLongValue(final Long longValue) { + this.longValue = longValue; + } + + @Override + public String getStringValue() { - return stringValue; ++ // workaround for Oracle DB considering empty string values as NULL (SYNCOPE-664) ++ return dateValue == null ++ && booleanValue == null ++ && longValue == null ++ && doubleValue == null ++ && binaryValue == null ++ && stringValue == null ++ ? StringUtils.EMPTY ++ : stringValue; + } + + @Override + public void setStringValue(final String stringValue) { + this.stringValue = stringValue; + } + + @Override + public byte[] getBinaryValue() { + return binaryValue; + } + + @Override + public void setBinaryValue(final byte[] binaryValue) { + this.binaryValue = ArrayUtils.clone(binaryValue); + } + + @Override + public void parseValue(final PlainSchema schema, final String value) throws ParsingValidationException { + Exception exception = null; + + switch (schema.getType()) { + + case Boolean: + this.setBooleanValue(Boolean.parseBoolean(value)); + break; + + case Long: + try { + this.setLongValue(schema.getConversionPattern() == null + ? Long.valueOf(value) + : DataFormat.parseNumber(value, schema.getConversionPattern()).longValue()); + } catch (Exception pe) { + exception = pe; + } + break; + + case Double: + try { + this.setDoubleValue(schema.getConversionPattern() == null + ? Double.valueOf(value) + : DataFormat.parseNumber(value, schema.getConversionPattern()).doubleValue()); + } catch (Exception pe) { + exception = pe; + } + break; + + case Date: + try { + this.setDateValue(schema.getConversionPattern() == null + ? DataFormat.parseDate(value) + : new Date(DataFormat.parseDate(value, schema.getConversionPattern()).getTime())); + } catch (Exception pe) { + exception = pe; + } + break; + + case Encrypted: + try { + this.setStringValue(Encryptor.getInstance(schema.getSecretKey()). + encode(value, schema.getCipherAlgorithm())); + } catch (Exception pe) { + exception = pe; + } + break; + + case Binary: + this.setBinaryValue(Base64.decodeBase64(value)); + break; + + case String: + case Enum: + default: + this.setStringValue(value); + } + + if (exception != null) { + throw new ParsingValidationException("While trying to parse '" + value + "' as " + schema.getKey(), + exception); + } + } + + @SuppressWarnings("unchecked") + @Override + public <T> T getValue() { + return (T) (booleanValue != null + ? getBooleanValue() + : dateValue != null + ? getDateValue() + : doubleValue != null + ? getDoubleValue() + : longValue != null + ? getLongValue() + : binaryValue != null + ? getBinaryValue() - : stringValue); ++ : getStringValue()); + } + + @Override + public String getValueAsString() { + final AttrSchemaType type = getAttr() == null || getAttr().getSchema() == null + || getAttr().getSchema().getType() == null + ? AttrSchemaType.String + : getAttr().getSchema().getType(); + + return getValueAsString(type); + } + + @Override + public String getValueAsString(final AttrSchemaType type) { + Exception exception = null; + + String result = null; + + switch (type) { + + case Boolean: + result = getBooleanValue().toString(); + break; + + case Long: + result = getAttr() == null || getAttr().getSchema() == null + || getAttr().getSchema().getConversionPattern() == null + ? getLongValue().toString() + : DataFormat.format(getLongValue(), getAttr().getSchema().getConversionPattern()); + break; + + case Double: + result = getAttr() == null || getAttr().getSchema() == null + || getAttr().getSchema().getConversionPattern() == null + ? getDoubleValue().toString() + : DataFormat.format(getDoubleValue(), getAttr().getSchema().getConversionPattern()); + break; + + case Date: + result = getAttr() == null || getAttr().getSchema() == null + || getAttr().getSchema().getConversionPattern() == null + ? DataFormat.format(getDateValue()) + : DataFormat.format(getDateValue(), false, getAttr().getSchema(). + getConversionPattern()); + break; + + case Binary: + result = Base64.encodeBase64String(getBinaryValue()); + break; + + case String: + case Enum: + case Encrypted: + default: + result = getStringValue(); + break; + } + + if (exception != null) { + throw new InvalidPlainAttrValueException( + "While trying to format '" + getValue() + "' as " + type, exception); + } + + return result; + } + + @Override + public String toString() { + return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE); + } +}
