Example usage for java.util Optional orElse

List of usage examples for java.util Optional orElse

Introduction

In this page you can find the example usage for java.util Optional orElse.

Prototype

public T orElse(T other) 

Source Link

Document

If a value is present, returns the value, otherwise returns other .

Usage

From source file:alfio.controller.EventController.java

@RequestMapping(value = "/event/{eventName}", method = { RequestMethod.GET, RequestMethod.HEAD })
public String showEvent(@PathVariable("eventName") String eventName, Model model, HttpServletRequest request,
        Locale locale) {/* w  w  w .ja  va 2 s  .  com*/

    return eventRepository.findOptionalByShortName(eventName)
            .filter(e -> e.getStatus() != Event.Status.DISABLED).map(event -> {
                Optional<String> maybeSpecialCode = SessionUtil.retrieveSpecialPriceCode(request);
                Optional<SpecialPrice> specialCode = maybeSpecialCode
                        .flatMap((trimmedCode) -> specialPriceRepository.getByCode(trimmedCode));

                Optional<PromoCodeDiscount> promoCodeDiscount = SessionUtil
                        .retrievePromotionCodeDiscount(request).flatMap((code) -> promoCodeRepository
                                .findPromoCodeInEventOrOrganization(event.getId(), code));

                final ZonedDateTime now = ZonedDateTime.now(event.getZoneId());
                //hide access restricted ticket categories
                List<TicketCategory> ticketCategories = ticketCategoryRepository
                        .findAllTicketCategories(event.getId());
                Map<Integer, String> categoriesDescription = ticketCategoryDescriptionRepository
                        .descriptionsByTicketCategory(ticketCategories.stream().map(TicketCategory::getId)
                                .collect(Collectors.toList()), locale.getLanguage());

                List<SaleableTicketCategory> saleableTicketCategories = ticketCategories.stream()
                        .filter((c) -> !c.isAccessRestricted() || (specialCode
                                .filter(sc -> sc.getTicketCategoryId() == c.getId()).isPresent()))
                        .map((m) -> new SaleableTicketCategory(m,
                                categoriesDescription.getOrDefault(m.getId(), ""), now, event,
                                ticketReservationManager.countAvailableTickets(event, m),
                                configurationManager.getIntConfigValue(
                                        Configuration.from(event.getOrganizationId(), event.getId(), m.getId(),
                                                ConfigurationKeys.MAX_AMOUNT_OF_TICKETS_BY_RESERVATION),
                                        5),
                                promoCodeDiscount.filter(promoCode -> shouldApplyDiscount(promoCode, m))
                                        .orElse(null)))
                        .collect(Collectors.toList());
                //

                final int orgId = event.getOrganizationId();
                final int eventId = event.getId();
                Map<ConfigurationKeys, Optional<String>> geoInfoConfiguration = configurationManager
                        .getStringConfigValueFrom(
                                Configuration.from(orgId, eventId, ConfigurationKeys.MAPS_PROVIDER),
                                Configuration.from(orgId, eventId, ConfigurationKeys.MAPS_CLIENT_API_KEY),
                                Configuration.from(orgId, eventId, ConfigurationKeys.MAPS_HERE_APP_ID),
                                Configuration.from(orgId, eventId, ConfigurationKeys.MAPS_HERE_APP_CODE));

                LocationDescriptor ld = LocationDescriptor.fromGeoData(event.getLatLong(),
                        TimeZone.getTimeZone(event.getTimeZone()), geoInfoConfiguration);

                final boolean hasAccessPromotions = ticketCategoryRepository
                        .countAccessRestrictedRepositoryByEventId(event.getId()) > 0
                        || promoCodeRepository.countByEventAndOrganizationId(event.getId(),
                                event.getOrganizationId()) > 0;

                String eventDescription = eventDescriptionRepository
                        .findDescriptionByEventIdTypeAndLocale(event.getId(),
                                EventDescription.EventDescriptionType.DESCRIPTION, locale.getLanguage())
                        .orElse("");

                final EventDescriptor eventDescriptor = new EventDescriptor(event, eventDescription);
                List<SaleableTicketCategory> expiredCategories = saleableTicketCategories.stream()
                        .filter(SaleableTicketCategory::getExpired).collect(Collectors.toList());
                List<SaleableTicketCategory> validCategories = saleableTicketCategories.stream()
                        .filter(tc -> !tc.getExpired()).collect(Collectors.toList());
                List<SaleableAdditionalService> additionalServices = additionalServiceRepository
                        .loadAllForEvent(event.getId()).stream().map((as) -> getSaleableAdditionalService(event,
                                locale, as, promoCodeDiscount.orElse(null)))
                        .collect(Collectors.toList());
                Predicate<SaleableTicketCategory> waitingQueueTargetCategory = tc -> !tc.getExpired()
                        && !tc.isBounded();
                boolean validPaymentConfigured = isEventHasValidPaymentConfigurations(event,
                        configurationManager);

                List<SaleableAdditionalService> notExpiredServices = additionalServices.stream()
                        .filter(SaleableAdditionalService::isNotExpired).collect(Collectors.toList());

                List<SaleableAdditionalService> supplements = adjustIndex(0,
                        notExpiredServices.stream()
                                .filter(a -> a.getType() == AdditionalService.AdditionalServiceType.SUPPLEMENT)
                                .collect(Collectors.toList()));
                List<SaleableAdditionalService> donations = adjustIndex(supplements.size(),
                        notExpiredServices.stream()
                                .filter(a -> a.getType() == AdditionalService.AdditionalServiceType.DONATION)
                                .collect(Collectors.toList()));

                model.addAttribute("event", eventDescriptor)//
                        .addAttribute("organization", organizationRepository.getById(event.getOrganizationId()))
                        .addAttribute("ticketCategories", validCategories)//
                        .addAttribute("expiredCategories", expiredCategories)//
                        .addAttribute("containsExpiredCategories", !expiredCategories.isEmpty())//
                        .addAttribute("showNoCategoriesWarning", validCategories.isEmpty())
                        .addAttribute("hasAccessPromotions", hasAccessPromotions)
                        .addAttribute("promoCode", specialCode.map(SpecialPrice::getCode).orElse(null))
                        .addAttribute("locationDescriptor", ld)
                        .addAttribute("pageTitle", "show-event.header.title")
                        .addAttribute("hasPromoCodeDiscount", promoCodeDiscount.isPresent())
                        .addAttribute("promoCodeDiscount", promoCodeDiscount.orElse(null))
                        .addAttribute("displayWaitingQueueForm",
                                EventUtil.displayWaitingQueueForm(event, saleableTicketCategories,
                                        configurationManager, eventStatisticsManager.noSeatsAvailable()))
                        .addAttribute("displayCategorySelectionForWaitingQueue",
                                saleableTicketCategories.stream().filter(waitingQueueTargetCategory)
                                        .count() > 1)
                        .addAttribute("unboundedCategories",
                                saleableTicketCategories.stream().filter(waitingQueueTargetCategory)
                                        .collect(Collectors.toList()))
                        .addAttribute("preSales", EventUtil.isPreSales(event, saleableTicketCategories))
                        .addAttribute("userLanguage", locale.getLanguage())
                        .addAttribute("showAdditionalServices", !notExpiredServices.isEmpty())
                        .addAttribute("showAdditionalServicesDonations", !donations.isEmpty())
                        .addAttribute("showAdditionalServicesSupplements", !supplements.isEmpty())
                        .addAttribute("enabledAdditionalServicesDonations", donations)
                        .addAttribute("enabledAdditionalServicesSupplements", supplements)
                        .addAttribute("forwardButtonDisabled",
                                (saleableTicketCategories.stream()
                                        .noneMatch(SaleableTicketCategory::getSaleable))
                                        || !validPaymentConfigured)
                        .addAttribute("useFirstAndLastName", event.mustUseFirstAndLastName())
                        .addAttribute("validPaymentMethodAvailable", validPaymentConfigured)
                        .addAttribute("validityStart", event.getBegin())
                        .addAttribute("validityEnd", event.getEnd());

                model.asMap().putIfAbsent("hasErrors", false);//
                return "/event/show-event";
            }).orElse(REDIRECT + "/");
}

From source file:com.blackducksoftware.integration.hub.detect.tool.signaturescanner.BlackDuckSignatureScannerTool.java

public SignatureScannerToolResult runScanTool(NameVersion projectNameVersion, Optional<File> dockerTar)
        throws DetectUserFriendlyException {
    DetectConfiguration detectConfiguration = detectContext.getBean(DetectConfiguration.class);
    DetectConfigurationFactory detectConfigurationFactory = detectContext
            .getBean(DetectConfigurationFactory.class);
    ConnectionManager connectionManager = detectContext.getBean(ConnectionManager.class);
    ConnectivityManager connectivityManager = detectContext.getBean(ConnectivityManager.class);
    DirectoryManager directoryManager = detectContext.getBean(DirectoryManager.class);

    Optional<BlackDuckServerConfig> hubServerConfig = Optional.empty();
    if (connectivityManager.isDetectOnline() && connectivityManager.getBlackDuckServerConfig().isPresent()) {
        hubServerConfig = connectivityManager.getBlackDuckServerConfig();
    }/*  w w  w  .  ja  v  a2 s  .c  om*/

    logger.info("Will run the signature scanner tool.");
    final String offlineLocalScannerInstallPath = detectConfiguration.getProperty(
            DetectProperty.DETECT_BLACKDUCK_SIGNATURE_SCANNER_OFFLINE_LOCAL_PATH, PropertyAuthority.None);
    final String onlineLocalScannerInstallPath = detectConfiguration
            .getProperty(DetectProperty.DETECT_BLACKDUCK_SIGNATURE_SCANNER_LOCAL_PATH, PropertyAuthority.None);

    String localScannerInstallPath = "";
    if (StringUtils.isNotBlank(offlineLocalScannerInstallPath)) {
        localScannerInstallPath = offlineLocalScannerInstallPath;
        logger.debug("Determined offline local scanner path: " + localScannerInstallPath);
    } else if (StringUtils.isNotBlank(onlineLocalScannerInstallPath)) {
        localScannerInstallPath = onlineLocalScannerInstallPath;
        logger.debug("Determined online local scanner path: " + localScannerInstallPath);
    }

    final String userProvidedScannerInstallUrl = detectConfiguration
            .getProperty(DetectProperty.DETECT_BLACKDUCK_SIGNATURE_SCANNER_HOST_URL, PropertyAuthority.None);

    BlackDuckSignatureScannerOptions blackDuckSignatureScannerOptions = detectConfigurationFactory
            .createBlackDuckSignatureScannerOptions();
    final ExecutorService executorService = Executors
            .newFixedThreadPool(blackDuckSignatureScannerOptions.getParrallelProcessors());
    IntEnvironmentVariables intEnvironmentVariables = new IntEnvironmentVariables();

    ScanBatchRunnerFactory scanBatchRunnerFactory = new ScanBatchRunnerFactory(intEnvironmentVariables,
            executorService);
    ScanBatchRunner scanBatchRunner;
    File installDirectory = directoryManager.getPermanentDirectory();
    if (hubServerConfig.isPresent() && StringUtils.isBlank(userProvidedScannerInstallUrl)
            && StringUtils.isBlank(localScannerInstallPath)) {
        logger.debug(
                "Signature scanner will use the hub server to download/update the scanner - this is the most likely situation.");
        scanBatchRunner = scanBatchRunnerFactory.withHubInstall(hubServerConfig.get());
    } else {
        if (StringUtils.isNotBlank(userProvidedScannerInstallUrl)) {
            logger.debug("Signature scanner will use the provided url to download/update the scanner.");
            scanBatchRunner = scanBatchRunnerFactory.withUserProvidedUrl(userProvidedScannerInstallUrl,
                    connectionManager);
        } else {
            logger.debug(
                    "Signature scanner either given an existing path for the scanner or is offline - either way, we won't attempt to manage the install.");
            if (StringUtils.isNotBlank(localScannerInstallPath)) {
                logger.debug("Using provided path: " + localScannerInstallPath);
                installDirectory = new File(localScannerInstallPath);
            } else {
                logger.debug("Using default scanner path.");
            }
            scanBatchRunner = scanBatchRunnerFactory.withoutInstall(installDirectory);
        }
    }
    logger.debug("Determined install directory: " + installDirectory.getAbsolutePath());

    try {
        if (hubServerConfig.isPresent()) {
            logger.debug("Signature scan is online.");
            CodeLocationCreationService codeLocationCreationService = connectivityManager
                    .getBlackDuckServicesFactory().get().createCodeLocationCreationService();
            OnlineBlackDuckSignatureScanner blackDuckSignatureScanner = detectContext.getBean(
                    OnlineBlackDuckSignatureScanner.class, signatureScannerOptions, scanBatchRunner,
                    codeLocationCreationService, hubServerConfig.get());
            CodeLocationCreationData<ScanBatchOutput> codeLocationCreationData = blackDuckSignatureScanner
                    .performOnlineScan(projectNameVersion, installDirectory, dockerTar.orElse(null));
            return SignatureScannerToolResult.createOnlineResult(codeLocationCreationData);
        } else {
            logger.debug("Signature scan is offline.");
            OfflineBlackDuckSignatureScanner blackDuckSignatureScanner = detectContext
                    .getBean(OfflineBlackDuckSignatureScanner.class, signatureScannerOptions, scanBatchRunner);
            ScanBatchOutput scanBatchOutput = blackDuckSignatureScanner.performScanActions(projectNameVersion,
                    installDirectory, dockerTar.orElse(null));
            return SignatureScannerToolResult.createOfflineResult(scanBatchOutput);
        }
    } catch (IOException | InterruptedException | IntegrationException e) {
        logger.info("Signature scan failed!");
        logger.debug("Signature scan error!", e);
        return SignatureScannerToolResult.createFailureResult();
    } finally {
        executorService.shutdownNow();
    }
}

From source file:com.ikanow.aleph2.data_model.utils.CrudServiceUtils.java

/** CRUD service proxy that optionally adds an extra term and allows the user to modify the results after they've run (eg to apply security service settings) 
 * @author Alex//  ww w  . j a va  2  s.  co m
 */
@SuppressWarnings("unchecked")
public static <T> ICrudService<T> intercept(final Class<T> clazz, final ICrudService<T> delegate,
        final Optional<QueryComponent<T>> extra_query,
        final Optional<Function<QueryComponent<T>, QueryComponent<T>>> query_transform,
        final Map<String, BiFunction<Object, Object[], Object>> interceptors,
        final Optional<BiFunction<Object, Object[], Object>> default_interceptor) {
    InvocationHandler handler = new InvocationHandler() {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            final Method m = delegate.getClass().getMethod(method.getName(), method.getParameterTypes());

            // First off, apply the extra term to any relevant args:
            final Object[] args_with_extra_query_pretransform = query_transform.map(q -> {
                return (null != args) ? Arrays.stream(args)
                        .map(o -> (null != o) && QueryComponent.class.isAssignableFrom(o.getClass())
                                ? q.apply((QueryComponent<T>) o)
                                : o)
                        .collect(Collectors.toList()).toArray() : args;
            }).orElse(args);

            final Object[] args_with_extra_query = extra_query.map(q -> {
                return (null != args_with_extra_query_pretransform)
                        ? Arrays.stream(args_with_extra_query_pretransform)
                                .map(o -> (null != o) && QueryComponent.class.isAssignableFrom(o.getClass())
                                        ? CrudUtils.allOf((QueryComponent<T>) o, q)
                                        : o)
                                .collect(Collectors.toList()).toArray()
                        : args_with_extra_query_pretransform;
            }).orElse(args_with_extra_query_pretransform);

            // Special cases for: readOnlyVersion, getFilterdRepo / countObjects / getRawService / *byId
            final Object o = Lambdas.get(() -> {
                final SingleQueryComponent<T> base_query = JsonNode.class.equals(clazz)
                        ? (SingleQueryComponent<T>) CrudUtils.allOf()
                        : CrudUtils.allOf(clazz);

                try {
                    if (extra_query.isPresent() && m.getName().equals("countObjects")) { // special case....change method and apply spec
                        return delegate.countObjectsBySpec(extra_query.get());
                    } else if (extra_query.isPresent() && m.getName().equals("getObjectById")) { // convert from id to spec and append extra_query
                        if (1 == args.length) {
                            return delegate.getObjectBySpec(CrudUtils.allOf(extra_query.get(),
                                    base_query.when(JsonUtils._ID, args[0])));
                        } else {
                            return delegate.getObjectBySpec(
                                    CrudUtils.allOf(extra_query.get(), base_query.when(JsonUtils._ID, args[0])),
                                    (List<String>) args[1], (Boolean) args[2]);
                        }
                    } else if (extra_query.isPresent() && m.getName().equals("deleteDatastore")) {
                        CompletableFuture<Long> l = delegate.deleteObjectsBySpec(extra_query.get());
                        return l.thenApply(ll -> ll > 0);
                    } else if (extra_query.isPresent() && m.getName().equals("deleteObjectById")) { // convert from id to spec and append extra_query
                        return delegate.deleteObjectBySpec(
                                CrudUtils.allOf(extra_query.get(), base_query.when(JsonUtils._ID, args[0])));
                    } else if (extra_query.isPresent() && m.getName().equals("updateObjectById")) { // convert from id to spec and append extra_query
                        return delegate.updateObjectBySpec(
                                CrudUtils.allOf(extra_query.get(), base_query.when(JsonUtils._ID, args[0])),
                                Optional.empty(), (UpdateComponent<T>) args[1]);
                    } else if (m.getName().equals("getRawService")) { // special case....convert the default query to JSON, if present
                        Object o_internal = m.invoke(delegate, args_with_extra_query);
                        Optional<QueryComponent<JsonNode>> json_extra_query = extra_query
                                .map(qc -> qc.toJson());
                        return intercept(JsonNode.class, (ICrudService<JsonNode>) o_internal, json_extra_query,
                                Optional.empty(), interceptors, default_interceptor);
                    } else { // wrap any CrudService types
                        Object o_internal = m.invoke(delegate, args_with_extra_query);
                        return (null != o_internal)
                                && ICrudService.class.isAssignableFrom(o_internal.getClass())
                                        ? intercept(clazz, (ICrudService<T>) o_internal, extra_query,
                                                Optional.empty(), interceptors, default_interceptor)
                                        : o_internal;
                    }
                } catch (IllegalAccessException ee) {
                    throw new RuntimeException(ee);
                } catch (InvocationTargetException e) {
                    throw new RuntimeException(e.getCause().getMessage(), e);
                }
            });

            return interceptors
                    .getOrDefault(m.getName(),
                            default_interceptor.orElse(CrudServiceUtils::identityInterceptor))
                    .apply(o, args_with_extra_query);
        }
    };

    return ICrudService.IReadOnlyCrudService.class.isAssignableFrom(delegate.getClass())
            ? (ICrudService<T>) Proxy.newProxyInstance(ICrudService.IReadOnlyCrudService.class.getClassLoader(),
                    new Class[] { ICrudService.IReadOnlyCrudService.class }, handler)
            : (ICrudService<T>) Proxy.newProxyInstance(ICrudService.class.getClassLoader(),
                    new Class[] { ICrudService.class }, handler);
}

From source file:org.apache.bookkeeper.mledger.impl.ManagedLedgerImpl.java

private void offloadLoop(CompletableFuture<PositionImpl> promise, Queue<LedgerInfo> ledgersToOffload,
        PositionImpl firstUnoffloaded, Optional<Throwable> firstError) {
    LedgerInfo info = ledgersToOffload.poll();
    if (info == null) {
        if (firstError.isPresent()) {
            promise.completeExceptionally(firstError.get());
        } else {/* w w w  . j ava  2  s. com*/
            promise.complete(firstUnoffloaded);
        }
    } else {
        long ledgerId = info.getLedgerId();
        UUID uuid = UUID.randomUUID();
        Map<String, String> extraMetadata = ImmutableMap.of("ManagedLedgerName", name);

        String driverName = config.getLedgerOffloader().getOffloadDriverName();
        Map<String, String> driverMetadata = config.getLedgerOffloader().getOffloadDriverMetadata();

        prepareLedgerInfoForOffloaded(ledgerId, uuid, driverName, driverMetadata)
                .thenCompose((ignore) -> getLedgerHandle(ledgerId))
                .thenCompose(readHandle -> config.getLedgerOffloader().offload(readHandle, uuid, extraMetadata))
                .thenCompose((ignore) -> {
                    return Retries
                            .run(Backoff.exponentialJittered(TimeUnit.SECONDS.toMillis(1),
                                    TimeUnit.SECONDS.toHours(1)).limit(10), FAIL_ON_CONFLICT,
                                    () -> completeLedgerInfoForOffloaded(ledgerId, uuid), scheduledExecutor,
                                    name)
                            .whenComplete((ignore2, exception) -> {
                                if (exception != null) {
                                    cleanupOffloaded(ledgerId, uuid, driverName, driverMetadata,
                                            "Metastore failure");
                                }
                            });
                }).whenComplete((ignore, exception) -> {
                    if (exception != null) {
                        log.info("[{}] Exception occurred during offload", name, exception);

                        PositionImpl newFirstUnoffloaded = PositionImpl.get(ledgerId, 0);
                        if (newFirstUnoffloaded.compareTo(firstUnoffloaded) > 0) {
                            newFirstUnoffloaded = firstUnoffloaded;
                        }
                        Optional<Throwable> errorToReport = firstError;
                        synchronized (ManagedLedgerImpl.this) {
                            // if the ledger doesn't exist anymore, ignore the error
                            if (ledgers.containsKey(ledgerId)) {
                                errorToReport = Optional.of(firstError.orElse(exception));
                            }
                        }

                        offloadLoop(promise, ledgersToOffload, newFirstUnoffloaded, errorToReport);
                    } else {
                        ledgerCache.remove(ledgerId);
                        offloadLoop(promise, ledgersToOffload, firstUnoffloaded, firstError);
                    }
                });
    }
}

From source file:org.silverpeas.core.admin.service.Admin.java

private SpaceInstLight getSpaceInstLight(int spaceId, int level) throws AdminException {
    Optional<SpaceInstLight> optionalSpace = treeCache.getSpaceInstLight(spaceId);
    final SpaceInstLight sil = optionalSpace.orElse(spaceManager.getSpaceInstLightById(spaceId));
    if (sil != null) {
        if (level != -1) {
            sil.setLevel(level);/* w  w  w.ja va 2  s .  c  om*/
        }
        if (sil.getLevel() == -1) {
            sil.setLevel(treeCache.getSpaceLevel(spaceId));
        }
    }
    return sil;
}

From source file:ca.oson.json.Oson.java

<T> T deserialize2Object(FieldData objectDTO) {
    Object valueToProcess = objectDTO.valueToProcess;
    Map<String, Object> map = null;

    if (valueToProcess != null && Map.class.isAssignableFrom(valueToProcess.getClass())) {
        map = (Map) valueToProcess;
    } else {//  w  w  w .jav  a  2  s .  c  o  m
        map = new HashMap<>();
    }

    Class<T> valueType = objectDTO.returnType;
    T obj = (T) objectDTO.returnObj;

    Set<String> nameKeys = new HashSet(map.keySet());

    if (valueType == null) {
        valueType = (Class<T>) obj.getClass();
    }

    // first build up the class-level processing rules

    ClassMapper classMapper = objectDTO.classMapper;
    //if (classMapper == null) {
    // 1. Create a blank class mapper instance
    classMapper = new ClassMapper(valueType);

    // 2. Globalize it
    classMapper = globalize(classMapper);
    objectDTO.classMapper = classMapper;
    //}

    if (objectDTO.fieldMapper != null && isInheritMapping()) {
        classMapper = overwriteBy(classMapper, objectDTO.fieldMapper);
    }

    objectDTO.incrLevel();

    try {
        boolean annotationSupport = getAnnotationSupport();
        Annotation[] annotations = null;

        if (annotationSupport) {
            ca.oson.json.annotation.ClassMapper classMapperAnnotation = null;

            // 3. Apply annotations from other sources
            annotations = valueType.getAnnotations();
            for (Annotation annotation : annotations) {
                if (ignoreClass(annotation)) {
                    return null;
                }

                switch (annotation.annotationType().getName()) {
                case "ca.oson.json.annotation.ClassMapper":
                    classMapperAnnotation = (ca.oson.json.annotation.ClassMapper) annotation;
                    if (!(classMapperAnnotation.serialize() == BOOLEAN.BOTH
                            || classMapperAnnotation.serialize() == BOOLEAN.FALSE)) {
                        classMapperAnnotation = null;
                    }
                    break;

                case "ca.oson.json.annotation.ClassMappers":
                    ca.oson.json.annotation.ClassMappers classMapperAnnotations = (ca.oson.json.annotation.ClassMappers) annotation;
                    for (ca.oson.json.annotation.ClassMapper ann : classMapperAnnotations.value()) {
                        if (ann.serialize() == BOOLEAN.BOTH || ann.serialize() == BOOLEAN.FALSE) {
                            classMapperAnnotation = ann;
                            // break;
                        }
                    }
                    break;

                case "com.google.gson.annotations.Since":
                    Since since = (Since) annotation;
                    classMapper.since = since.value();
                    break;

                case "com.google.gson.annotations.Until":
                    Until until = (Until) annotation;
                    classMapper.until = until.value();
                    break;

                case "com.fasterxml.jackson.annotation.JsonIgnoreProperties":
                    JsonIgnoreProperties jsonIgnoreProperties = (JsonIgnoreProperties) annotation;
                    String[] jsonnames = jsonIgnoreProperties.value();
                    if (jsonnames != null && jsonnames.length > 0) {
                        if (classMapper.jsonIgnoreProperties == null) {
                            classMapper.jsonIgnoreProperties = new HashSet();
                        }

                        classMapper.jsonIgnoreProperties.addAll(Arrays.asList(jsonnames));
                    }
                    break;

                case "org.codehaus.jackson.annotate.JsonIgnoreProperties":
                    org.codehaus.jackson.annotate.JsonIgnoreProperties jsonIgnoreProperties2 = (org.codehaus.jackson.annotate.JsonIgnoreProperties) annotation;
                    String[] jsonnames2 = jsonIgnoreProperties2.value();
                    if (jsonnames2 != null && jsonnames2.length > 0) {
                        if (classMapper.jsonIgnoreProperties == null) {
                            classMapper.jsonIgnoreProperties = new HashSet();
                        }

                        classMapper.jsonIgnoreProperties.addAll(Arrays.asList(jsonnames2));
                    }
                    break;

                case "com.fasterxml.jackson.annotation.JsonPropertyOrder":
                    // first come first serve
                    if (classMapper.propertyOrders == null) {
                        classMapper.propertyOrders = ((JsonPropertyOrder) annotation).value();
                    }
                    break;

                case "org.codehaus.jackson.annotate.JsonPropertyOrder":
                    // first come first serve
                    if (classMapper.propertyOrders == null) {
                        classMapper.propertyOrders = ((org.codehaus.jackson.annotate.JsonPropertyOrder) annotation)
                                .value();
                    }
                    break;

                case "com.fasterxml.jackson.annotation.JsonInclude":
                    if (classMapper.defaultType == JSON_INCLUDE.NONE) {
                        JsonInclude jsonInclude = (JsonInclude) annotation;
                        switch (jsonInclude.content()) {
                        case ALWAYS:
                            classMapper.defaultType = JSON_INCLUDE.ALWAYS;
                            break;
                        case NON_NULL:
                            classMapper.defaultType = JSON_INCLUDE.NON_NULL;
                            break;
                        case NON_ABSENT:
                            classMapper.defaultType = JSON_INCLUDE.NON_NULL;
                            break;
                        case NON_EMPTY:
                            classMapper.defaultType = JSON_INCLUDE.NON_EMPTY;
                            break;
                        case NON_DEFAULT:
                            classMapper.defaultType = JSON_INCLUDE.NON_DEFAULT;
                            break;
                        case USE_DEFAULTS:
                            classMapper.defaultType = JSON_INCLUDE.DEFAULT;
                            break;
                        }
                    }
                    break;

                case "com.fasterxml.jackson.annotation.JsonAutoDetect":
                    JsonAutoDetect jsonAutoDetect = (JsonAutoDetect) annotation;
                    if (jsonAutoDetect.fieldVisibility() == Visibility.NONE) {
                        classMapper.useField = false;
                    } else if (jsonAutoDetect.fieldVisibility() != Visibility.DEFAULT) {
                        classMapper.useField = true;
                    }
                    if (jsonAutoDetect.setterVisibility() == Visibility.NONE) {
                        classMapper.useAttribute = false;
                    } else if (jsonAutoDetect.setterVisibility() != Visibility.DEFAULT) {
                        classMapper.useAttribute = true;
                    }

                    break;

                case "org.codehaus.jackson.annotate.JsonAutoDetect":
                    org.codehaus.jackson.annotate.JsonAutoDetect jsonAutoDetect2 = (org.codehaus.jackson.annotate.JsonAutoDetect) annotation;
                    if (jsonAutoDetect2
                            .fieldVisibility() == org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE) {
                        classMapper.useField = false;
                    }
                    if (jsonAutoDetect2
                            .getterVisibility() == org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE) {
                        classMapper.useAttribute = false;
                    }

                    break;

                case "org.junit.Ignore":
                    classMapper.ignore = true;
                    break;
                }
            }

            // 4. Apply annotations from Oson
            if (classMapperAnnotation != null) {
                classMapper = overwriteBy(classMapper, classMapperAnnotation);
            }
        }

        // 5. Apply Java configuration for this particular class
        ClassMapper javaClassMapper = getClassMapper(valueType);
        if (javaClassMapper != null) {
            classMapper = overwriteBy(classMapper, javaClassMapper);
        }

        // now processing at the class level

        if (classMapper.ignore()) {
            return null;
        }

        if (classMapper.since != null && classMapper.since > getVersion()) {
            return null;
        } else if (classMapper.until != null && classMapper.until <= getVersion()) {
            return null;
        }

        Function function = classMapper.deserializer; // = getDeserializer(valueType);
        if (function == null) {
            function = DeSerializerUtil.getDeserializer(valueType.getName());
        }
        if (function != null) {
            try {
                Object returnedValue = null;
                if (function instanceof Json2DataMapperFunction) {
                    DataMapper classData = new DataMapper(valueToProcess, valueType, obj, classMapper,
                            objectDTO.level, getPrettyIndentation());
                    Json2DataMapperFunction f = (Json2DataMapperFunction) function;

                    return (T) f.apply(classData);

                } else if (function instanceof Json2FieldDataFunction) {
                    Json2FieldDataFunction f = (Json2FieldDataFunction) function;
                    FieldData fieldData = objectDTO.clone();

                    returnedValue = f.apply(fieldData);

                } else {
                    returnedValue = function.apply(obj);
                }

                if (returnedValue instanceof Optional) {
                    Optional opt = (Optional) returnedValue;
                    returnedValue = opt.orElse(null);
                }

                if (returnedValue == null) {
                    return null;
                } else if (valueType.isAssignableFrom(returnedValue.getClass())) {
                    return (T) returnedValue;
                } else {
                    // not the correct returned object type, do nothing
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        Map<String, Method> getters = getGetters(valueType);
        Map<String, Method> setters = getSetters(valueType);
        Map<String, Method> otherMethods = getOtherMethods(valueType);
        Set<String> processedNameSet = new HashSet<>();

        Method jsonAnySetterMethod = null;

        Field[] fields = getFields(valueType); // getFields(obj);

        FIELD_NAMING format = getFieldNaming();

        // @Expose
        boolean exposed = false;
        if (isUseGsonExpose()) {
            // check if @exposed is used any where
            if (valueType.isAnnotationPresent(com.google.gson.annotations.Expose.class)) {
                exposed = true;
            }
            if (!exposed) {
                for (Field f : fields) {
                    if (f.isAnnotationPresent(com.google.gson.annotations.Expose.class)) {
                        exposed = true;
                        break;
                    }
                }
            }
        }

        for (Field f : fields) {
            String name = f.getName();
            String fieldName = name;
            String lcfieldName = name.toLowerCase();

            Class<?> returnType = f.getType(); // value.getClass();

            if (Modifier.isFinal(f.getModifiers()) && Modifier.isStatic(f.getModifiers())) {
                setters.remove(lcfieldName);
                nameKeys.remove(name);
                continue;
            }

            f.setAccessible(true);

            // getter and setter methods

            Method getter = null;
            Method setter = null;
            if (getters != null) {
                getter = getters.get(lcfieldName);
            }
            if (setters != null) {
                setter = setters.get(lcfieldName);
            }

            if (ignoreModifiers(f.getModifiers(), classMapper.includeFieldsWithModifiers)) {
                if (setter != null) {
                    if (ignoreModifiers(setter.getModifiers(), classMapper.includeFieldsWithModifiers)) {
                        setters.remove(lcfieldName);
                        nameKeys.remove(name);
                        continue;
                    }

                } else {
                    continue;
                }
            }

            // 6. Create a blank field mapper instance
            // using valueType of enclosing obj
            FieldMapper fieldMapper = new FieldMapper(name, name, valueType);

            // 7. get the class mapper of returnType
            ClassMapper fieldClassMapper = getClassMapper(returnType);

            // 8. Classify this field mapper with returnType
            fieldMapper = classifyFieldMapper(fieldMapper, fieldClassMapper);

            // 9. Classify this field mapper with enclosing class type
            fieldMapper = classifyFieldMapper(fieldMapper, classMapper);

            FieldMapper javaFieldMapper = getFieldMapper(name, null, valueType);

            boolean ignored = false;

            if (setter != null) {
                setter.setAccessible(true);
            }

            Set<String> names = new HashSet<>();

            if (annotationSupport) {
                annotations = f.getAnnotations();

                if (setter != null
                        && ((javaFieldMapper == null || javaFieldMapper.useAttribute == null)
                                && (fieldMapper.useAttribute == null || fieldMapper.useAttribute))
                        || (javaFieldMapper != null && javaFieldMapper.isDeserializing()
                                && javaFieldMapper.useAttribute != null && javaFieldMapper.useAttribute)) {
                    annotations = Stream
                            .concat(Arrays.stream(annotations), Arrays.stream(setter.getDeclaredAnnotations()))
                            .toArray(Annotation[]::new);
                }

                // no annotations, then try get method
                if ((annotations == null || annotations.length == 0) && getter != null) {
                    annotations = getter.getDeclaredAnnotations();
                }

                ca.oson.json.annotation.FieldMapper fieldMapperAnnotation = null;

                boolean exposexists = false;
                for (Annotation annotation : annotations) {
                    if (ignoreField(annotation, classMapper.ignoreFieldsWithAnnotations)) {
                        ignored = true;
                        break;

                    } else if (annotation instanceof ca.oson.json.annotation.FieldMapper) {
                        fieldMapperAnnotation = (ca.oson.json.annotation.FieldMapper) annotation;
                        if (!(fieldMapperAnnotation.serialize() == BOOLEAN.BOTH
                                || fieldMapperAnnotation.serialize() == BOOLEAN.FALSE)) {
                            fieldMapperAnnotation = null;
                        }

                    } else if (annotation instanceof ca.oson.json.annotation.FieldMappers) {
                        ca.oson.json.annotation.FieldMappers fieldMapperAnnotations = (ca.oson.json.annotation.FieldMappers) annotation;
                        for (ca.oson.json.annotation.FieldMapper ann : fieldMapperAnnotations.value()) {
                            if (ann.serialize() == BOOLEAN.BOTH || ann.serialize() == BOOLEAN.FALSE) {
                                fieldMapperAnnotation = ann;
                                //break; to enable the last one wins
                            }
                        }

                    } else {

                        switch (annotation.annotationType().getName()) {

                        case "com.fasterxml.jackson.annotation.JsonAnySetter":
                        case "org.codehaus.jackson.annotate.JsonAnySetter":
                            fieldMapper.jsonAnySetter = true;
                            break;

                        case "javax.persistence.Transient":
                            fieldMapper.ignore = true;
                            break;

                        case "com.fasterxml.jackson.annotation.JsonIgnore":
                        case "org.codehaus.jackson.annotate.JsonIgnore":
                            fieldMapper.ignore = true;
                            break;

                        case "com.fasterxml.jackson.annotation.JsonIgnoreProperties":
                            JsonIgnoreProperties jsonIgnoreProperties = (JsonIgnoreProperties) annotation;
                            if (!jsonIgnoreProperties.allowSetters()) {
                                fieldMapper.ignore = true;
                            } else {
                                fieldMapper.ignore = false;
                                classMapper.jsonIgnoreProperties.remove(name);
                            }
                            break;

                        case "com.google.gson.annotations.Expose":
                            Expose expose = (Expose) annotation;
                            if (!expose.deserialize()) {
                                fieldMapper.ignore = true;
                            }
                            exposexists = true;
                            break;

                        case "com.google.gson.annotations.Since":
                            Since since = (Since) annotation;
                            fieldMapper.since = since.value();
                            break;

                        case "com.google.gson.annotations.Until":
                            Until until = (Until) annotation;
                            fieldMapper.until = until.value();
                            break;

                        case "com.google.gson.annotations.SerializedName":
                            SerializedName serializedName = (SerializedName) annotation;
                            String[] alternates = serializedName.alternate();

                            if (alternates != null && alternates.length > 0) {
                                for (String alternate : alternates) {
                                    names.add(alternate);
                                }
                            }
                            break;

                        case "com.fasterxml.jackson.annotation.JsonInclude":
                            if (fieldMapper.defaultType == JSON_INCLUDE.NONE) {
                                JsonInclude jsonInclude = (JsonInclude) annotation;

                                switch (jsonInclude.content()) {
                                case ALWAYS:
                                    fieldMapper.defaultType = JSON_INCLUDE.ALWAYS;
                                    break;
                                case NON_NULL:
                                    fieldMapper.defaultType = JSON_INCLUDE.NON_NULL;
                                    break;
                                case NON_ABSENT:
                                    fieldMapper.defaultType = JSON_INCLUDE.NON_NULL;
                                    break;
                                case NON_EMPTY:
                                    fieldMapper.defaultType = JSON_INCLUDE.NON_EMPTY;
                                    break;
                                case NON_DEFAULT:
                                    fieldMapper.defaultType = JSON_INCLUDE.NON_DEFAULT;
                                    break;
                                case USE_DEFAULTS:
                                    fieldMapper.defaultType = JSON_INCLUDE.DEFAULT;
                                    break;
                                }
                            }
                            break;

                        case "com.fasterxml.jackson.annotation.JsonRawValue":
                            if (((JsonRawValue) annotation).value()) {
                                fieldMapper.jsonRawValue = true;
                            }
                            break;

                        case "org.codehaus.jackson.annotate.JsonRawValue":
                            if (((org.codehaus.jackson.annotate.JsonRawValue) annotation).value()) {
                                fieldMapper.jsonRawValue = true;
                            }
                            break;

                        case "org.junit.Ignore":
                            fieldMapper.ignore = true;
                            break;

                        case "javax.persistence.Enumerated":
                            fieldMapper.enumType = ((Enumerated) annotation).value();
                            break;

                        case "javax.validation.constraints.NotNull":
                            fieldMapper.required = true;
                            break;

                        case "com.fasterxml.jackson.annotation.JsonProperty":
                            JsonProperty jsonProperty = (JsonProperty) annotation;
                            Access access = jsonProperty.access();
                            if (access == Access.READ_ONLY) {
                                fieldMapper.ignore = true;
                            }

                            if (jsonProperty.required()) {
                                fieldMapper.required = true;
                            }

                            if (fieldMapper.defaultValue == null) {
                                fieldMapper.defaultValue = jsonProperty.defaultValue();
                            }
                            break;

                        case "javax.validation.constraints.Size":
                            Size size = (Size) annotation;
                            if (size.min() > 0) {
                                fieldMapper.min = (long) size.min();
                            }
                            if (size.max() < Integer.MAX_VALUE) {
                                fieldMapper.max = (long) size.max();
                            }
                            break;

                        case "javax.persistence.Column":
                            Column column = (Column) annotation;
                            if (column.length() != 255) {
                                fieldMapper.length = column.length();
                            }
                            if (column.scale() > 0) {
                                fieldMapper.scale = column.scale();
                            }
                            if (column.precision() > 0) {
                                fieldMapper.precision = column.precision();
                            }

                            if (!column.nullable()) {
                                fieldMapper.required = true;
                            }
                            break;
                        }

                        String fname = ObjectUtil.getName(annotation);
                        if (!StringUtil.isEmpty(fname)) {
                            names.add(fname);
                        }

                    }
                }

                if (exposed && !exposexists) {
                    fieldMapper.ignore = true;
                }

                // 10. Apply annotations from Oson
                if (fieldMapperAnnotation != null) {
                    fieldMapper = overwriteBy(fieldMapper, fieldMapperAnnotation, classMapper);
                }
            }

            if (ignored) {
                nameKeys.remove(name);
                nameKeys.remove(fieldMapper.json);
                setters.remove(lcfieldName);
                if (exposed) {
                    setNull(f, obj);
                }
                continue;
            }

            // 11. Apply Java configuration for this particular field
            if (javaFieldMapper != null && javaFieldMapper.isDeserializing()) {
                fieldMapper = overwriteBy(fieldMapper, javaFieldMapper);
            }

            if (fieldMapper.ignore != null && fieldMapper.ignore) {
                if (setter != null) {
                    setters.remove(lcfieldName);
                }
                nameKeys.remove(name);
                nameKeys.remove(fieldMapper.json);
                if (exposed) {
                    setNull(f, obj);
                }
                continue;
            }

            // in the ignored list
            if (ObjectUtil.inSet(name, classMapper.jsonIgnoreProperties)) {
                setters.remove(lcfieldName);
                nameKeys.remove(name);
                continue;
            }

            if (fieldMapper.jsonAnySetter != null && fieldMapper.jsonAnySetter && setter != null) {
                setters.remove(lcfieldName);
                otherMethods.put(lcfieldName, setter);
                continue;
            }

            if (fieldMapper.useField != null && !fieldMapper.useField) {
                // both should not be used, just like ignore
                if (fieldMapper.useAttribute != null && !fieldMapper.useAttribute) {
                    getters.remove(lcfieldName);
                }
                continue;
            }

            if (fieldMapper.since != null && fieldMapper.since > getVersion()) {
                if (setter != null) {
                    setters.remove(lcfieldName);
                }
                continue;
            } else if (fieldMapper.until != null && fieldMapper.until <= getVersion()) {
                if (setter != null) {
                    setters.remove(lcfieldName);
                }
                continue;
            }

            // get value for name in map
            Object value = null;
            boolean jnameFixed = false;
            String json = fieldMapper.json;
            int size = nameKeys.size();
            if (json == null) {
                if (setter != null) {
                    setters.remove(lcfieldName);
                }
                continue;

            } else if (!json.equals(name)) {
                name = json;
                value = getMapValue(map, name, nameKeys);
                jnameFixed = true;
            }

            if (!jnameFixed) {
                for (String jsoname : names) {
                    if (!name.equals(jsoname) && !StringUtil.isEmpty(jsoname)) {
                        name = jsoname;
                        value = getMapValue(map, name, nameKeys);
                        if (value != null) {
                            jnameFixed = true;
                            break;
                        }
                    }
                }
            }

            if (!jnameFixed) {
                value = getMapValue(map, name, nameKeys);
                jnameFixed = true;
            }

            fieldMapper.java = fieldName;
            fieldMapper.json = name;

            // either not null, or a null value exists in the value map
            if (value != null || size == nameKeys.size() + 1) {
                Object oldValue = value;
                FieldData fieldData = new FieldData(obj, f, value, returnType, true, fieldMapper,
                        objectDTO.level, objectDTO.set);
                fieldData.setter = setter;
                Class fieldType = guessComponentType(fieldData);
                value = json2Object(fieldData);

                if (StringUtil.isNull(value)) {
                    if (classMapper.defaultType == JSON_INCLUDE.NON_NULL
                            || classMapper.defaultType == JSON_INCLUDE.NON_EMPTY
                            || classMapper.defaultType == JSON_INCLUDE.NON_DEFAULT) {
                        continue;

                    }

                } else if (StringUtil.isEmpty(value)) {
                    if (classMapper.defaultType == JSON_INCLUDE.NON_EMPTY
                            || classMapper.defaultType == JSON_INCLUDE.NON_DEFAULT) {
                        continue;
                    }

                } else if (DefaultValue.isDefault(value, returnType)) {
                    if (classMapper.defaultType == JSON_INCLUDE.NON_DEFAULT) {
                        continue;
                    }
                }

                try {
                    if (value == null && oldValue != null && oldValue.equals(f.get(obj) + "")) {
                        // keep original value

                    } else {
                        f.set(obj, value);
                    }

                } catch (IllegalAccessException | IllegalArgumentException ex) {
                    //ex.printStackTrace();
                    if (setter != null) {
                        ObjectUtil.setMethodValue(obj, setter, value);
                    }
                }
            }

            setters.remove(lcfieldName);
            nameKeys.remove(name);
        }

        for (Entry<String, Method> entry : setters.entrySet()) {
            String lcfieldName = entry.getKey();
            Method setter = entry.getValue();

            setter.setAccessible(true);

            String name = setter.getName();
            if (name != null && name.length() > 3 && name.substring(0, 3).equals("set")
                    && name.substring(3).equalsIgnoreCase(lcfieldName)) {
                name = StringUtil.uncapitalize(name.substring(3));
            }

            // just use field name, even it might not be a field
            String fieldName = name;

            if (ignoreModifiers(setter.getModifiers(), classMapper.includeFieldsWithModifiers)) {
                nameKeys.remove(name);
                continue;
            }

            if (Modifier.isFinal(setter.getModifiers()) && Modifier.isStatic(setter.getModifiers())) {
                nameKeys.remove(name);
                continue;
            }

            // 6. Create a blank field mapper instance
            FieldMapper fieldMapper = new FieldMapper(name, name, valueType);

            Class returnType = null;
            Class[] types = setter.getParameterTypes();
            if (types != null && types.length > 0) {
                returnType = types[0];
            }

            // not a proper setter
            if (returnType == null) {
                continue;
            }

            // 7. get the class mapper of returnType
            ClassMapper fieldClassMapper = getClassMapper(returnType);

            // 8. Classify this field mapper with returnType
            fieldMapper = classifyFieldMapper(fieldMapper, fieldClassMapper);

            // 9. Classify this field mapper with enclosing class type
            fieldMapper = classifyFieldMapper(fieldMapper, classMapper);

            FieldMapper javaFieldMapper = getFieldMapper(name, null, valueType);

            boolean ignored = false;

            Method getter = getters.get(lcfieldName);

            Set<String> names = new HashSet<>();

            if (annotationSupport) {

                annotations = setter.getDeclaredAnnotations();

                // no annotations, then try get method
                if ((annotations == null || annotations.length == 0) && getter != null) {
                    annotations = getter.getDeclaredAnnotations();
                }

                ca.oson.json.annotation.FieldMapper fieldMapperAnnotation = null;

                for (Annotation annotation : annotations) {
                    if (ignoreField(annotation, classMapper.ignoreFieldsWithAnnotations)) {
                        ignored = true;
                        break;

                    } else if (annotation instanceof ca.oson.json.annotation.FieldMapper) {
                        fieldMapperAnnotation = (ca.oson.json.annotation.FieldMapper) annotation;
                        if (!(fieldMapperAnnotation.serialize() == BOOLEAN.BOTH
                                || fieldMapperAnnotation.serialize() == BOOLEAN.FALSE)) {
                            fieldMapperAnnotation = null;
                        }

                    } else if (annotation instanceof ca.oson.json.annotation.FieldMappers) {
                        ca.oson.json.annotation.FieldMappers fieldMapperAnnotations = (ca.oson.json.annotation.FieldMappers) annotation;
                        for (ca.oson.json.annotation.FieldMapper ann : fieldMapperAnnotations.value()) {
                            if (ann.serialize() == BOOLEAN.BOTH || ann.serialize() == BOOLEAN.FALSE) {
                                fieldMapperAnnotation = ann;
                                // break;
                            }
                        }

                    } else {
                        // to improve performance, using swith on string
                        switch (annotation.annotationType().getName()) {
                        case "com.fasterxml.jackson.annotation.JsonAnySetter":
                        case "org.codehaus.jackson.annotate.JsonAnySetter":
                            fieldMapper.jsonAnySetter = true;
                            break;

                        case "javax.persistence.Transient":
                            fieldMapper.ignore = true;
                            break;

                        case "com.fasterxml.jackson.annotation.JsonIgnore":
                        case "org.codehaus.jackson.annotate.JsonIgnore":
                            fieldMapper.ignore = true;
                            break;

                        case "com.fasterxml.jackson.annotation.JsonIgnoreProperties":
                            JsonIgnoreProperties jsonIgnoreProperties = (JsonIgnoreProperties) annotation;
                            if (!jsonIgnoreProperties.allowSetters()) {
                                fieldMapper.ignore = true;
                            } else {
                                fieldMapper.ignore = false;
                                classMapper.jsonIgnoreProperties.remove(name);
                            }
                            break;

                        case "com.google.gson.annotations.Expose":
                            Expose expose = (Expose) annotation;
                            if (!expose.deserialize()) {
                                fieldMapper.ignore = true;
                            }
                            break;

                        case "com.google.gson.annotations.Since":
                            Since since = (Since) annotation;
                            fieldMapper.since = since.value();
                            break;

                        case "com.google.gson.annotations.Until":
                            Until until = (Until) annotation;
                            fieldMapper.until = until.value();
                            break;

                        case "com.fasterxml.jackson.annotation.JsonInclude":
                            if (fieldMapper.defaultType == JSON_INCLUDE.NONE) {
                                JsonInclude jsonInclude = (JsonInclude) annotation;

                                switch (jsonInclude.content()) {
                                case ALWAYS:
                                    fieldMapper.defaultType = JSON_INCLUDE.ALWAYS;
                                    break;
                                case NON_NULL:
                                    fieldMapper.defaultType = JSON_INCLUDE.NON_NULL;
                                    break;
                                case NON_ABSENT:
                                    fieldMapper.defaultType = JSON_INCLUDE.NON_NULL;
                                    break;
                                case NON_EMPTY:
                                    fieldMapper.defaultType = JSON_INCLUDE.NON_EMPTY;
                                    break;
                                case NON_DEFAULT:
                                    fieldMapper.defaultType = JSON_INCLUDE.NON_DEFAULT;
                                    break;
                                case USE_DEFAULTS:
                                    fieldMapper.defaultType = JSON_INCLUDE.DEFAULT;
                                    break;
                                }
                            }
                            break;

                        case "com.fasterxml.jackson.annotation.JsonRawValue":
                            if (((JsonRawValue) annotation).value()) {
                                fieldMapper.jsonRawValue = true;
                            }
                            break;

                        case "org.codehaus.jackson.annotate.JsonRawValue":
                            if (((org.codehaus.jackson.annotate.JsonRawValue) annotation).value()) {
                                fieldMapper.jsonRawValue = true;
                            }
                            break;

                        case "org.junit.Ignore":
                            fieldMapper.ignore = true;
                            break;

                        case "javax.persistence.Enumerated":
                            fieldMapper.enumType = ((Enumerated) annotation).value();
                            break;

                        case "javax.validation.constraints.NotNull":
                            fieldMapper.required = true;
                            break;

                        case "com.fasterxml.jackson.annotation.JsonProperty":
                            JsonProperty jsonProperty = (JsonProperty) annotation;
                            Access access = jsonProperty.access();
                            if (access == Access.READ_ONLY) {
                                fieldMapper.ignore = true;
                            }

                            if (jsonProperty.required()) {
                                fieldMapper.required = true;
                            }

                            if (fieldMapper.defaultValue == null) {
                                fieldMapper.defaultValue = jsonProperty.defaultValue();
                            }
                            break;

                        case "javax.validation.constraints.Size":
                            Size size = (Size) annotation;
                            if (size.min() > 0) {
                                fieldMapper.min = (long) size.min();
                            }
                            if (size.max() < Integer.MAX_VALUE) {
                                fieldMapper.max = (long) size.max();
                            }
                            break;

                        case "javax.persistence.Column":
                            Column column = (Column) annotation;
                            if (column.length() != 255) {
                                fieldMapper.length = column.length();
                            }
                            if (column.scale() > 0) {
                                fieldMapper.scale = column.scale();
                            }
                            if (column.precision() > 0) {
                                fieldMapper.precision = column.precision();
                            }

                            if (!column.nullable()) {
                                fieldMapper.required = true;
                            }
                            break;
                        }

                        String fname = ObjectUtil.getName(annotation);
                        if (fname != null) {
                            names.add(fname);
                        }
                    }
                }

                // 10. Apply annotations from Oson
                if (fieldMapperAnnotation != null) {
                    fieldMapper = overwriteBy(fieldMapper, fieldMapperAnnotation, classMapper);
                }
            }

            if (ignored) {
                nameKeys.remove(name);
                nameKeys.remove(fieldMapper.json);
                continue;
            }

            // 11. Apply Java configuration for this particular field
            if (javaFieldMapper != null && javaFieldMapper.isDeserializing()) {
                fieldMapper = overwriteBy(fieldMapper, javaFieldMapper);
            }

            if (fieldMapper.ignore != null && fieldMapper.ignore) {
                nameKeys.remove(name);
                nameKeys.remove(fieldMapper.json);
                continue;
            }

            // in the ignored list
            if (ObjectUtil.inSet(name, classMapper.jsonIgnoreProperties)) {
                nameKeys.remove(name);
                continue;
            }

            if (fieldMapper.useAttribute != null && !fieldMapper.useAttribute) {
                nameKeys.remove(name);
                nameKeys.remove(fieldMapper.json);
                continue;
            }

            if (fieldMapper.jsonAnySetter != null && fieldMapper.jsonAnySetter && setter != null) {
                setters.remove(lcfieldName);
                otherMethods.put(lcfieldName, setter);
                continue;
            }

            if (fieldMapper.since != null && fieldMapper.since > getVersion()) {
                nameKeys.remove(name);
                nameKeys.remove(fieldMapper.json);
                continue;
            } else if (fieldMapper.until != null && fieldMapper.until <= getVersion()) {
                nameKeys.remove(name);
                nameKeys.remove(fieldMapper.json);
                continue;
            }

            // get value for name in map
            Object value = null;
            boolean jnameFixed = false;
            String json = fieldMapper.json;
            if (json == null) {
                continue;

            } else if (!json.equals(name)) {
                name = json;
                value = getMapValue(map, name, nameKeys);
                jnameFixed = true;
            }

            if (!jnameFixed) {
                for (String jsoname : names) {
                    if (!name.equals(jsoname) && !StringUtil.isEmpty(jsoname)) {
                        name = jsoname;
                        value = getMapValue(map, name, nameKeys);
                        jnameFixed = true;
                        break;
                    }
                }
            }

            if (!jnameFixed) {
                value = getMapValue(map, name, nameKeys);
                jnameFixed = true;
            }

            fieldMapper.java = fieldName;
            fieldMapper.json = name;

            if (value != null) {

                FieldData fieldData = new FieldData(obj, null, value, returnType, true, fieldMapper,
                        objectDTO.level, objectDTO.set);
                fieldData.setter = setter;
                Class fieldType = guessComponentType(fieldData);

                value = json2Object(fieldData);

                if (StringUtil.isNull(value)) {
                    if (classMapper.defaultType == JSON_INCLUDE.NON_NULL
                            || classMapper.defaultType == JSON_INCLUDE.NON_EMPTY
                            || classMapper.defaultType == JSON_INCLUDE.NON_DEFAULT) {
                        continue;

                    }

                } else if (StringUtil.isEmpty(value)) {
                    if (classMapper.defaultType == JSON_INCLUDE.NON_EMPTY
                            || classMapper.defaultType == JSON_INCLUDE.NON_DEFAULT) {
                        continue;
                    }

                } else if (DefaultValue.isDefault(value, returnType)) {
                    if (classMapper.defaultType == JSON_INCLUDE.NON_DEFAULT) {
                        continue;
                    }
                }

                ObjectUtil.setMethodValue(obj, setter, value);

                nameKeys.remove(name);
            }
        }

        if (annotationSupport) {
            //@JsonAnySetter
            if (nameKeys.size() > 0) {
                for (Entry<String, Method> entry : otherMethods.entrySet()) {
                    Method method = entry.getValue();

                    if (ignoreModifiers(method.getModifiers(), classMapper.includeFieldsWithModifiers)) {
                        continue;
                    }

                    if (method.isAnnotationPresent(JsonAnySetter.class)) {
                        if (ignoreField(JsonAnySetter.class, classMapper.ignoreFieldsWithAnnotations)) {
                            continue;
                        }

                        jsonAnySetterMethod = method;

                    } else if (method.isAnnotationPresent(org.codehaus.jackson.annotate.JsonAnySetter.class)) {
                        if (ignoreField(org.codehaus.jackson.annotate.JsonAnySetter.class,
                                classMapper.ignoreFieldsWithAnnotations)) {
                            continue;
                        }

                        jsonAnySetterMethod = method;

                    } else if (method.isAnnotationPresent(ca.oson.json.annotation.FieldMapper.class)) {
                        ca.oson.json.annotation.FieldMapper annotation = (ca.oson.json.annotation.FieldMapper) method
                                .getAnnotation(ca.oson.json.annotation.FieldMapper.class);
                        if (annotation.jsonAnySetter() == BOOLEAN.TRUE) {
                            jsonAnySetterMethod = method;
                            break;
                        }
                    }
                }
            }
        }

        if (jsonAnySetterMethod != null) {
            Parameter[] parameters = jsonAnySetterMethod.getParameters();
            if (parameters != null && parameters.length == 2) {
                for (String name : nameKeys) {
                    Object value = map.get(name);

                    // json to java, check if this name is allowed or changed
                    String java = json2Java(name);

                    if (value != null && !StringUtil.isEmpty(java)) {
                        ObjectUtil.setMethodValue(obj, jsonAnySetterMethod, java, value);
                    }

                }
            }
        }

        return obj;

        // | InvocationTargetException
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    }

    return null;
}