How do I convert a Boolean to String using Dozer? - dozer

I am new to Dozer and I am trying to map a String to a Boolean and vica versa. Can anyone tell me does Dozer support this or do I have to create a custom converter. The string will contain true or false so will map directly. Also I am using the Dozer API and not the XML config. Thanks for your help

I don't think dozer supports this out of the box, you can use a custom converter to do this work for you. In fact the help page on custom converters uses this case as example:
public class NewDozerConverter extends DozerConverter<String, Boolean> {
public NewDozerConverter() {
super(String.class, Boolean.class);
}
public Boolean convertTo(String source, Boolean destination) {
if ("true".equals(source)) {
return Boolean.TRUE;
} else if ("false".equals(source)) {
return Boolean.FALSE;
}
throw new IllegalStateException("Unknown value!");
}
public String convertFrom(Boolean source, String destination) {
if (Boolean.TRUE.equals(source)) {
return "true";
} else if (Boolean.FALSE.equals(source)) {
return "false";
}
throw new IllegalStateException("Unknown value!");
}
}

Related

Why ContentFragment.adaptTo() return null?

I want to create a custom sling model which can be adapted from com.adobe.cq.dam.cfm.ContentFragment
like below,
import com.adobe.cq.dam.cfm.ContentFragment;
#Model(adaptables = ContentFragment.class, adapters = EventInfo.class)
public class EventInfoImpl implements EventInfo{
#Self
ContentFragment cf;
#Override
public String getTitle(){
return cf.getElement("title").getContent();
}
}
but in a caller class,
EventInfo e = contentFragment.adaptTo(EventInfo.class);
adaptTo() returns null.(variable "e" is null)
Why adaptTo() returns null? and How do I adapt correctly in this case?
Sling models can only be adapted from Resource or SlingHttpServletRequest. For anything else you need a classic AdapterFactory.
https://sling.apache.org/apidocs/sling11/org/apache/sling/api/adapter/AdapterFactory.html
How to implement a custom AdapterFactory for Sling Resource?
You can see it in the Sling source code of the ModelAdapterFactory. There is the method createModel:
<ModelType> ModelType createModel(#NotNull Object adaptable, #NotNull Class<ModelType> type)
https://github.com/apache/sling-org-apache-sling-models-impl/blob/master/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java
If you dig down, the real filtering happens in the helper-class AdapterImplementations (line 258-268)
https://github.com/apache/sling-org-apache-sling-models-impl/blob/master/src/main/java/org/apache/sling/models/impl/AdapterImplementations.java
if (adaptableType == Resource.class) {
map = resourceTypeMappingsForResources;
resourceTypeRemovalLists = resourceTypeRemovalListsForResources;
} else if (adaptableType == SlingHttpServletRequest.class) {
map = resourceTypeMappingsForRequests;
resourceTypeRemovalLists = resourceTypeRemovalListsForRequests;
} else {
log.warn("Found model class {} with resource type {} for adaptable {}. Unsupported type for resourceType binding.",
new Object[] { clazz, resourceType, adaptableType });
return;
}

How can I ignore a "$" in a DocumentContent to save in MongoDB?

My Problem is, that if I save a Document with a $ inside the content, Mongodb gives me an exception:
java.lang.IllegalArgumentException: Invalid BSON field name $ xxx
I would like that mongodb ignores the $ character in the content.
My Application is written in java. I read the content of the File and put it as a string into an object. After that the object will be saved with a MongoRepository class.
Someone has any ideas??
Example content
Edit: I heard mongodb has the same problem wit dot. Our Springboot found i workaround with dot, but not for dollar.
How to configure mongo converter in spring to encode all dots in the keys of map being saved in mongo db
If you are using Spring Boot you can extend MappingMongoConverter class and add override methods that do the escaping/unescaping.
#Component
public class MappingMongoConverterCustom extends MappingMongoConverter {
protected #Nullable
String mapKeyDollarReplacemant = "characters_to_replace_dollar";
protected #Nullable
String mapKeyDotReplacement = "characters_to_replace_dot";
public MappingMongoConverterCustom(DbRefResolver dbRefResolver, MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext) {
super(dbRefResolver, mappingContext);
}
#Override
protected String potentiallyEscapeMapKey(String source) {
if (!source.contains(".") && !source.contains("$")) {
return source;
}
if (mapKeyDotReplacement == null && mapKeyDollarReplacemant == null) {
throw new MappingException(String.format(
"Map key %s contains dots or dollars but no replacement was configured! Make "
+ "sure map keys don't contain dots or dollars in the first place or configure an appropriate replacement!",
source));
}
String result = source;
if(result.contains(".")) {
result = result.replaceAll("\\.", mapKeyDotReplacement);
}
if(result.contains("$")) {
result = result.replaceAll("\\$", mapKeyDollarReplacemant);
}
//add any other replacements you need
return result;
}
#Override
protected String potentiallyUnescapeMapKey(String source) {
String result = source;
if(mapKeyDotReplacement != null) {
result = result.replaceAll(mapKeyDotReplacement, "\\.");
}
if(mapKeyDollarReplacemant != null) {
result = result.replaceAll(mapKeyDollarReplacemant, "\\$");
}
//add any other replacements you need
return result;
}
}
If you go with this approach make sure you override the default converter from AbstractMongoConfiguration like below:
#Configuration
public class MongoConfig extends AbstractMongoConfiguration{
#Bean
public DbRefResolver getDbRefResolver() {
return new DefaultDbRefResolver(mongoDbFactory());
}
#Bean
#Override
public MappingMongoConverter mappingMongoConverter() throws Exception {
MappingMongoConverterCustom converter = new MappingMongoConverterCustom(getDbRefResolver(), mongoMappingContext());
converter.setCustomConversions(customConversions());
return converter;
}
.... whatever you might need extra ...
}

Mongodb scala driver custom conversion to JSON

If I am using "native" json support from mongodb oficial scala driver:
val jsonText = Document(...).toJson()
it produces json text with type prefixes for extended types:
{ "$oid" : "AABBb...." } - for ObjectID,
{ "$longNumber" : 123123 } - for Long and etc.
I want to avoid such type conversion and write directly just values for each type. Is it possible somehow to overwrite encoding behavior for some type?
You can subclass JsonWriter and override writeXXX methods. For example, to customize date serialization you can use:
class CustomJsonWriter extends JsonWriter {
public CustomJsonWriter(Writer writer) {
super(writer);
}
public CustomJsonWriter(Writer writer, JsonWriterSettings settings) {
super(writer, settings);
}
#Override
protected void doWriteDateTime(long value) {
doWriteString(DateTimeFormatter.ISO_DATE_TIME
.withZone(ZoneId.of("Z"))
.format(Instant.ofEpochMilli(value)));
}
}
And then you can use the overridden version that way:
public static String toJson(Document doc) {
CustomJsonWriter writer = new CustomJsonWriter(new StringWriter(), new JsonWriterSettings());
DocumentCodec encoder = new DocumentCodec();
encoder.encode(writer, doc, EncoderContext.builder().isEncodingCollectibleDocument(true).build());
return writer.getWriter().toString();
}

Error : Cannot find Facebook SDK Version

the SDK 7.x is not working on Unity 5.1.0f3 , i always got the error version not found .
does someone have see this error ?
Actually, it's just a warning. But you can fix it.
There are several places where facebook plugin calls
FBBuildVersionAttribute.GetVersionAttributeOfType(typeof(AbstractFacebook));
So first, you need to modify FBBuildVersionAttribute to this:
// we are going to apply this attribute to Class
// instead of Assembly
// also make it inheritable for all implementations
[AttributeUsage(AttributeTargets.Class, Inherited = true)]
public class FBBuildVersionAttribute : Attribute
{
private DateTime buildDate;
private string buildHash;
private string buildVersion;
private string sdkVersion;
public DateTime Date { get { return buildDate; } }
public string Hash { get { return buildHash; } }
public string SdkVersion { get { return sdkVersion; } }
public string BuildVersion { get { return buildVersion; } }
public FBBuildVersionAttribute(string sdkVersion, string buildVersion)
{
this.buildVersion = buildVersion;
var parts = buildVersion.Split('.');
buildDate = DateTime.ParseExact(parts[0], "yyMMdd", System.Globalization.CultureInfo.InvariantCulture);
buildHash = parts[1];
this.sdkVersion = sdkVersion;
}
public override string ToString()
{
return buildVersion;
}
public static FBBuildVersionAttribute GetVersionAttributeOfType(Type type)
{
foreach (FBBuildVersionAttribute attribute in getAttributes(type))
{
return attribute;
}
return null;
}
private static FBBuildVersionAttribute[] getAttributes(Type type)
{
if (type == null)
throw new ArgumentNullException("type");
// we want to get attributes from type instead of assmebly
return (FBBuildVersionAttribute[])(type.GetCustomAttributes(typeof(FBBuildVersionAttribute), false));
}
}
No you just need to add this attribute to AbstractFacebook:
[FBBuildVersionAttribute("7.0.1", "150604.98558e55096475c")]
public abstract class AbstractFacebook : MonoBehaviour
{
// ...
}
Note that 98558e55096475c part is trash string. It's not actual build hash, cause I don't have one.
Get the latest version of the FB Unity SDK. Change log says it's fixed now.
https://developers.facebook.com/docs/unity/change-log

Refactoring two basic classes

How would you refactor these two classes to abstract out the similarities? An abstract class? Simple inheritance? What would the refactored class(es) look like?
public class LanguageCode
{
/// <summary>
/// Get the lowercase two-character ISO 639-1 language code.
/// </summary>
public readonly string Value;
public LanguageCode(string language)
{
this.Value = new CultureInfo(language).TwoLetterISOLanguageName;
}
public static LanguageCode TryParse(string language)
{
if (language == null)
{
return null;
}
if (language.Length > 2)
{
language = language.Substring(0, 2);
}
try
{
return new LanguageCode(language);
}
catch (ArgumentException)
{
return null;
}
}
}
public class RegionCode
{
/// <summary>
/// Get the uppercase two-character ISO 3166 region/country code.
/// </summary>
public readonly string Value;
public RegionCode(string region)
{
this.Value = new RegionInfo(region).TwoLetterISORegionName;
}
public static RegionCode TryParse(string region)
{
if (region == null)
{
return null;
}
if (region.Length > 2)
{
region = region.Substring(0, 2);
}
try
{
return new RegionCode(region);
}
catch (ArgumentException)
{
return null;
}
}
}
It depends, if they are not going to do much more, then I would probably leave them as is - IMHO factoring out stuff is likely to be more complex, in this case.
Unless you have a strong reason for refactoring (because you are going to add more classes like those in near future) the penalty of changing the design for such a small and contrived example would overcome the gain in maintenance or overhead in this scenario. Anyhow here is a possible design based on generic and lambda expressions.
public class TwoLetterCode<T>
{
private readonly string value;
public TwoLetterCode(string value, Func<string, string> predicate)
{
this.value = predicate(value);
}
public static T TryParse(string value, Func<string, T> predicate)
{
if (value == null)
{
return default(T);
}
if (value.Length > 2)
{
value = value.Substring(0, 2);
}
try
{
return predicate(value);
}
catch (ArgumentException)
{
return default(T);
}
}
public string Value { get { return this.value; } }
}
public class LanguageCode : TwoLetterCode<LanguageCode> {
public LanguageCode(string language)
: base(language, v => new CultureInfo(v).TwoLetterISOLanguageName)
{
}
public static LanguageCode TryParse(string language)
{
return TwoLetterCode<LanguageCode>.TryParse(language, v => new LanguageCode(v));
}
}
public class RegionCode : TwoLetterCode<RegionCode>
{
public RegionCode(string language)
: base(language, v => new CultureInfo(v).TwoLetterISORegionName)
{
}
public static RegionCode TryParse(string language)
{
return TwoLetterCode<RegionCode>.TryParse(language, v => new RegionCode(v));
}
}
This is a rather simple question and to me smells awefully like a homework assignment.
You can obviously see the common bits in the code and I'm pretty sure you can make an attempt at it yourself by putting such things into a super-class.
You could maybe combine them into a Locale class, which stores both Language code and Region code, has accessors for Region and Language plus one parse function which also allows for strings like "en_gb"...
That's how I've seen locales be handled in various frameworks.
These two, as they stand, aren't going to refactor well because of the static methods.
You'd either end up with some kind of factory method on a base class that returns an a type of that base class (which would subsequently need casting) or you'd need some kind of additional helper class.
Given the amount of extra code and subsequent casting to the appropriate type, it's not worth it.
Create a generic base class (eg AbstractCode<T>)
add abstract methods like
protected T GetConstructor(string code);
override in base classes like
protected override RegionCode GetConstructor(string code)
{
return new RegionCode(code);
}
Finally, do the same with string GetIsoName(string code), eg
protected override GetIsoName(string code)
{
return new RegionCode(code).TowLetterISORegionName;
}
That will refactor the both. Chris Kimpton does raise the important question as to whether the effort is worth it.
I'm sure there is a better generics based solution. But still gave it a shot.
EDIT: As the comment says, static methods can't be overridden so one option would be to retain it and use TwoLetterCode objects around and cast them, but, as some other person has already pointed out, that is rather useless.
How about this?
public class TwoLetterCode {
public readonly string Value;
public static TwoLetterCode TryParseSt(string tlc) {
if (tlc == null)
{
return null;
}
if (tlc.Length > 2)
{
tlc = tlc.Substring(0, 2);
}
try
{
return new TwoLetterCode(tlc);
}
catch (ArgumentException)
{
return null;
}
}
}
//Likewise for Region
public class LanguageCode : TwoLetterCode {
public LanguageCode(string language)
{
this.Value = new CultureInfo(language).TwoLetterISOLanguageName;
}
public static LanguageCode TryParse(string language) {
return (LanguageCode)TwoLetterCode.TryParseSt(language);
}
}