001/* 002 * Portions of this software was developed by employees of the National Institute 003 * of Standards and Technology (NIST), an agency of the Federal Government and is 004 * being made available as a public service. Pursuant to title 17 United States 005 * Code Section 105, works of NIST employees are not subject to copyright 006 * protection in the United States. This software may be subject to foreign 007 * copyright. Permission in the United States and in foreign countries, to the 008 * extent that NIST may hold copyright, to use, copy, modify, create derivative 009 * works, and distribute this software and its documentation without fee is hereby 010 * granted on a non-exclusive basis, provided that this notice and disclaimer 011 * of warranty appears in all copies. 012 * 013 * THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER 014 * EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY 015 * THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF 016 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM 017 * INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE 018 * SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT 019 * SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, 020 * INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, 021 * OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, 022 * CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR 023 * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT 024 * OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER. 025 */ 026 027package gov.nist.secauto.metaschema.core.datatype.adapter; 028 029import com.fasterxml.jackson.core.JsonGenerator; 030import com.fasterxml.jackson.core.JsonParser; 031import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatTypes; 032 033import gov.nist.secauto.metaschema.core.datatype.AbstractDataTypeAdapter; 034import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException; 035import gov.nist.secauto.metaschema.core.metapath.item.atomic.IAnyAtomicItem; 036import gov.nist.secauto.metaschema.core.metapath.item.atomic.IBooleanItem; 037import gov.nist.secauto.metaschema.core.metapath.item.atomic.INumericItem; 038import gov.nist.secauto.metaschema.core.metapath.item.atomic.IStringItem; 039import gov.nist.secauto.metaschema.core.util.ObjectUtils; 040 041import java.io.IOException; 042import java.util.List; 043 044import edu.umd.cs.findbugs.annotations.NonNull; 045 046public class BooleanAdapter 047 extends AbstractDataTypeAdapter<Boolean, IBooleanItem> { 048 @NonNull 049 private static final List<String> NAMES = ObjectUtils.notNull( 050 List.of("boolean")); 051 052 BooleanAdapter() { 053 super(Boolean.class); 054 } 055 056 @Override 057 public List<String> getNames() { 058 return NAMES; 059 } 060 061 @Override 062 public JsonFormatTypes getJsonRawType() { 063 return JsonFormatTypes.BOOLEAN; 064 } 065 066 @SuppressWarnings("null") 067 @Override 068 public Boolean parse(String value) { 069 return Boolean.valueOf(value); 070 } 071 072 @Override 073 public Boolean parse(JsonParser parser) throws IOException { 074 Boolean value = parser.getBooleanValue(); 075 // skip over value 076 parser.nextToken(); 077 return value; 078 } 079 080 @Override 081 public void writeJsonValue(Object value, JsonGenerator generator) 082 throws IOException { 083 try { 084 generator.writeBoolean((Boolean) value); 085 } catch (ClassCastException ex) { 086 throw new IOException(ex); 087 } 088 } 089 090 @Override 091 public Boolean copy(Object obj) { 092 // the value is immutable 093 return (Boolean) obj; 094 } 095 096 @Override 097 public Class<IBooleanItem> getItemClass() { 098 return IBooleanItem.class; 099 } 100 101 @Override 102 public IBooleanItem newItem(Object value) { 103 Boolean item = toValue(value); 104 return IBooleanItem.valueOf(item); 105 } 106 107 @Override 108 protected IBooleanItem castInternal(@NonNull IAnyAtomicItem item) { 109 IBooleanItem retval; 110 if (item instanceof INumericItem) { 111 retval = castToBoolean((INumericItem) item); 112 } else if (item instanceof IStringItem) { 113 retval = castToBoolean((IStringItem) item); 114 } else { 115 retval = castToBoolean(item.newStringItem()); 116 } 117 return retval; 118 } 119 120 /** 121 * Cast the provided numeric value to a boolean. Any non-zero value will be 122 * {@code true}, or {@code false} otherwise. 123 * 124 * @param item 125 * the item to cast 126 * @return {@code true} if the item value is non-zero, or {@code false} 127 * otherwise 128 */ 129 @NonNull 130 protected IBooleanItem castToBoolean(@NonNull INumericItem item) { 131 return IBooleanItem.valueOf(item.toEffectiveBoolean()); 132 } 133 134 /** 135 * If the string is a numeric value, treat it as so. Otherwise parse the value 136 * as a boolean string. 137 * 138 * @param item 139 * the item to cast 140 * @return the effective boolean value of the string 141 * @throws InvalidValueForCastFunctionException 142 * if the provided item cannot be cast to a boolean value by any means 143 */ 144 @NonNull 145 protected IBooleanItem castToBoolean(@NonNull IStringItem item) { 146 IBooleanItem retval; 147 try { 148 INumericItem numeric = INumericItem.cast(item); 149 retval = castToBoolean(numeric); 150 } catch (InvalidValueForCastFunctionException ex) { 151 retval = super.castInternal(item); 152 } 153 return retval; 154 } 155 156}