de.pksoftware.springstrap.cms.util.CmsUtils.java Source code

Java tutorial

Introduction

Here is the source code for de.pksoftware.springstrap.cms.util.CmsUtils.java

Source

/*
 * 
 * Springstrap
 *
 * @author Jan Philipp Knller <info@pksoftware.de>
 * 
 * Homepage: http://ui5strap.com/springstrap
 *
 * Copyright (c) 2013-2014 Jan Philipp Knller <info@pksoftware.de>
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * Released under Apache2 license: http://www.apache.org/licenses/LICENSE-2.0.txt
 * 
 */

package de.pksoftware.springstrap.cms.util;

import java.io.StringReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.json.Json;
import javax.json.JsonArray;
import javax.json.JsonString;
import javax.json.JsonObject;
import javax.json.JsonReader;
import javax.json.JsonValue;

import org.apache.commons.lang3.math.NumberUtils;
import org.json.JSONObject;
import org.json.JSONArray;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;

import de.pksoftware.springstrap.cms.entity.CmsModel;
import de.pksoftware.springstrap.cms.exception.InvalidPathException;

public class CmsUtils {

    private static final Logger logger = LoggerFactory.getLogger(CmsUtils.class);

    /*
    public static String getModelProperty2(CmsModel model, String path, String defaultValue){
       Assert.notNull(model);
           
       Pattern pattern = Pattern.compile("^(\\/\\w+)+$");  
       Matcher matcher = pattern.matcher(path);  
           
       if(!matcher.matches()){
     throw new RuntimeException("Path must start with /, must not end with / and must only contain letters and numbers.");
       }
           
       String value = defaultValue;
           
       logger.info("Trying to get " + model.getModelName() + ">" + path);
           
         
       String data = model.getData();
            
       String[] pathParts = path.split("\\/");
       int partsLength = pathParts.length;
           
       JSONObject jsonObject = new JSONObject(data);
           
       boolean pointerIsArray = false;
       Object pointer = jsonObject;
           
       for(int i = 1; i < partsLength; i++){
     Assert.notNull(pointer);
         
     String pathPart = pathParts[i];
     logger.info("Testing property: " + pathPart);
         
     Object jsonValue = null;
         
     if(pointerIsArray){
        if(!NumberUtils.isNumber(pathPart)){
           throw new RuntimeException(pathPart + " is not numeric.");
        }
        JSONArray arrayPointer = ((JSONArray) pointer);
        int arrayIndex = Integer.parseInt(pathPart);
        if(arrayIndex >= arrayPointer.length()){
           throw new RuntimeException(arrayIndex + " is out of bounds.");
        }
        jsonValue = arrayPointer.opt(arrayIndex);
     }
     else{
        jsonValue = ((JSONObject) pointer).opt(pathPart);
     }
         
     if(null == jsonValue){
        logger.info(model.getModelName() + " has no property: " + pathPart);
            
        break;
     }
         
     if(i < partsLength-1){
        //Must be Object or Array
        if(jsonValue instanceof JSONArray){
           logger.info(pathPart + " is an array.");
           pointer = (JSONArray) jsonValue;
           pointerIsArray = true;
        }
        else if(jsonValue instanceof JSONObject){
           logger.info(pathPart + " is an object.");
           pointer = (JSONObject) jsonValue;
           pointerIsArray = false;
        }
        else{
           throw new RuntimeException("Path parts need to be an array or object.");
        }
     }
     else{
        if(jsonValue instanceof String){
           logger.info(pathPart + " is an string.");
           value = (String)jsonValue;
           break;
        }
        else{
           throw new RuntimeException("Path end part need to be a String");
        }
     }
       }
           
       return value;
    }
    */

    public static String getModelProperty(CmsModel model, String path, String defaultValue)
            throws InvalidPathException {
        if (null == model) {
            return defaultValue;
        }

        Pattern pattern = Pattern.compile("^(\\/\\w+)+$");
        Matcher matcher = pattern.matcher(path);

        if (!matcher.matches()) {
            throw new RuntimeException(
                    "Path must start with /, must not end with / and must only contain letters and numbers.");
        }

        String value = defaultValue;

        logger.info("Trying to get " + model.getModelName() + ">" + path);

        String data = model.getData();

        String[] pathParts = path.split("\\/");
        int partsLength = pathParts.length;

        JsonReader jsonReader = Json.createReader(new StringReader(data));
        JsonObject jsonObject = jsonReader.readObject();

        boolean pointerIsArray = false;
        Object pointer = jsonObject;

        for (int i = 1; i < partsLength; i++) {
            String pathPart = pathParts[i];
            logger.info("Testing property: " + pathPart);
            JsonValue jsonValue = null;
            Assert.notNull(pointer);
            if (pointerIsArray) {
                if (!NumberUtils.isNumber(pathPart)) {
                    throw new InvalidPathException("Path element '" + pathPart + "' should be numeric.");
                }
                jsonValue = ((JsonArray) pointer).get(Integer.parseInt(pathPart));
            } else {
                jsonValue = ((JsonObject) pointer).get(pathPart);
            }

            if (null == jsonValue) {
                logger.info(model.getModelName() + " has no property: " + path);

                break;
            }

            JsonValue.ValueType valueType = jsonValue.getValueType();
            if (i < partsLength - 1) {
                //Must be Object or Array
                if (valueType == JsonValue.ValueType.ARRAY) {
                    logger.info(pathPart + " is an array.");
                    pointer = (JsonArray) jsonValue;
                    pointerIsArray = true;
                } else if (valueType == JsonValue.ValueType.OBJECT) {
                    logger.info(pathPart + " is an object.");
                    pointer = (JsonObject) jsonValue;
                    pointerIsArray = false;
                } else {
                    throw new InvalidPathException("Path element '" + pathPart
                            + "' should be a be an object or array, but " + valueType.toString() + " found.");
                }
            } else {
                if (valueType == JsonValue.ValueType.STRING) {
                    logger.info(pathPart + " is an string.");
                    value = ((JsonString) jsonValue).getString();
                    break;
                } else {
                    throw new InvalidPathException("Path element '" + pathPart + "' should be a string, but "
                            + valueType.toString() + " found.");
                }
            }
        }

        jsonReader.close();

        return value;
    }

    /**
     * 
     * @param model
     * @param path
     * @param value
     * @throws InvalidPathException 
     */
    public static String setModelProperty(CmsModel model, String path, String value) throws InvalidPathException {
        Assert.notNull(model);

        Pattern pattern = Pattern.compile("^(\\/\\w+)+$");
        Matcher matcher = pattern.matcher(path);

        if (!matcher.matches()) {
            throw new RuntimeException(
                    "Path must start with /, must not end with / and must only contain letters and numbers.");
        }

        logger.info("Trying to set " + model.getModelName() + ">" + path);

        String data = model.getData();

        String[] pathParts = path.split("\\/");
        int partsLength = pathParts.length;

        JSONObject jsonObject = new JSONObject(data);

        boolean pointerIsArray = false;
        Object pointer = jsonObject;

        for (int i = 1; i < partsLength; i++) {
            Assert.notNull(pointer);

            String pathPart = pathParts[i];
            logger.info("Testing property: " + pathPart);

            Object jsonValue = null;

            if (pointerIsArray) {
                if (!NumberUtils.isNumber(pathPart)) {
                    throw new InvalidPathException("Path element '" + pathPart + "' should be numeric.");
                }
                JSONArray arrayPointer = ((JSONArray) pointer);
                int arrayIndex = Integer.parseInt(pathPart);
                jsonValue = arrayPointer.opt(arrayIndex);

                if (null == jsonValue && i < partsLength - 1) {
                    //Decide whether we want to create a new array or object
                    String nextPathPart = pathParts[i + 1];
                    if (NumberUtils.isNumber(nextPathPart)) {
                        jsonValue = new JSONArray();
                    } else {
                        jsonValue = new JSONObject();
                    }

                    arrayPointer.put(arrayIndex, jsonValue);
                }
            } else {
                JSONObject objectPointer = ((JSONObject) pointer);
                jsonValue = objectPointer.opt(pathPart);

                if (null == jsonValue && i < partsLength - 1) {
                    //Decide whether we want to create a new array or object
                    String nextPathPart = pathParts[i + 1];
                    if (NumberUtils.isNumber(nextPathPart)) {
                        jsonValue = new JSONArray();
                    } else {
                        jsonValue = new JSONObject();
                    }
                    objectPointer.put(pathPart, jsonValue);
                }
            }

            if (i < partsLength - 1) {
                //Must be Object or Array
                if (jsonValue instanceof JSONArray) {
                    logger.info(pathPart + " is an array.");
                    pointer = (JSONArray) jsonValue;
                    pointerIsArray = true;
                } else if (jsonValue instanceof JSONObject) {
                    logger.info(pathPart + " is an object.");
                    pointer = (JSONObject) jsonValue;
                    pointerIsArray = false;
                } else {
                    throw new InvalidPathException(
                            "Path element '" + pathPart + "' should be a be an object or array, but "
                                    + jsonValue.getClass().toString() + " found.");
                }
            } else {
                if (null != jsonValue && !(jsonValue instanceof String)) {
                    throw new InvalidPathException("Path element '" + pathPart + "' should be a be a string, but "
                            + jsonValue.getClass().toString() + " found.");
                }

                if (pointerIsArray) {
                    if (!NumberUtils.isNumber(pathPart)) {
                        throw new InvalidPathException("Path element '" + pathPart + "' should be numeric.");
                    }
                    ((JSONArray) pointer).put(Integer.parseInt(pathPart), value);
                } else {
                    ((JSONObject) pointer).put(pathPart, value);
                }

                break;

            }
        }

        return jsonObject.toString();
    }

}