001/* 002 * oauth2-oidc-sdk 003 * 004 * Copyright 2012-2016, Connect2id Ltd and contributors. 005 * 006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use 007 * this file except in compliance with the License. You may obtain a copy of the 008 * License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software distributed 013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 015 * specific language governing permissions and limitations under the License. 016 */ 017 018package com.nimbusds.oauth2.sdk.util; 019 020 021import java.util.LinkedList; 022import java.util.List; 023 024import com.nimbusds.oauth2.sdk.ParseException; 025 026import net.minidev.json.parser.JSONParser; 027import net.minidev.json.writer.JsonReader; 028 029 030/** 031 * JSON helper methods. 032 */ 033public final class JSONUtils { 034 035 036 /** 037 * Parses a JSON value. 038 * 039 * @param s The JSON string to parse. Must not be {@code null}. 040 * 041 * @return The JSON value. 042 * 043 * @throws ParseException If the string cannot be parsed to a JSON 044 * value. 045 */ 046 public static Object parseJSON(final String s) 047 throws ParseException { 048 049 try { 050 return new JSONParser(JSONParser.USE_HI_PRECISION_FLOAT | JSONParser.ACCEPT_TAILLING_SPACE).parse(s); 051 } catch (net.minidev.json.parser.ParseException e) { 052 throw new ParseException("Invalid JSON: " + e.getMessage(), e); 053 } catch (NullPointerException e) { 054 throw new ParseException("The JSON string must not be null", e); 055 } catch (Exception e) { 056 throw new ParseException("Unexpected exception: " + e.getMessage(), e); 057 } catch (Error e) { 058 // Guard against unexpected java.lang.Error instances 059 throw new ParseException("Unexpected error: " + e.getMessage(), e); 060 } 061 } 062 063 064 /** 065 * Parses a JSON value while keeping the order of JSON object members. 066 * 067 * @param s The JSON string to parse. Must not be {@code null}. 068 * 069 * @return The JSON value. 070 * 071 * @throws ParseException If the string cannot be parsed to a JSON 072 * value. 073 */ 074 public static Object parseJSONKeepingOrder(final String s) 075 throws ParseException { 076 077 try { 078 return new JSONParser(JSONParser.USE_HI_PRECISION_FLOAT | JSONParser.ACCEPT_TAILLING_SPACE).parse(s, new JsonReader().DEFAULT_ORDERED); 079 080 } catch (net.minidev.json.parser.ParseException e) { 081 082 throw new ParseException("Invalid JSON: " + e.getMessage(), e); 083 } 084 } 085 086 087 /** 088 * Casts an object. 089 * 090 * @param o The object. Must not be {@code null}. 091 * @param clazz The expected class of the object. Must not be 092 * {@code null}. 093 * 094 * @return The cast object. 095 * 096 * @throws ParseException If the object is not of the expected type. 097 */ 098 @SuppressWarnings("unchecked") 099 public static <T> T to(final Object o, final Class<T> clazz) 100 throws ParseException { 101 102 if (! clazz.isAssignableFrom(o.getClass())) 103 throw new ParseException("Unexpected type: " + o.getClass()); 104 105 return (T)o; 106 } 107 108 109 /** 110 * Casts an object to a boolean. 111 * 112 * @param o The object. Must not be {@code null}. 113 * 114 * @return The boolean value. 115 * 116 * @throws ParseException If the object is not of the expected type. 117 */ 118 public static boolean toBoolean(final Object o) 119 throws ParseException { 120 121 return to(o, Boolean.class); 122 } 123 124 125 /** 126 * Casts an object to a number. 127 * 128 * @param o The object. Must not be {@code null}. 129 * 130 * @return The number. 131 * 132 * @throws ParseException If the object is not of the expected type. 133 */ 134 public static Number toNumber(final Object o) 135 throws ParseException { 136 137 return to(o, Number.class); 138 } 139 140 141 /** 142 * Casts an object to a string. 143 * 144 * @param o The object. Must not be {@code null}. 145 * 146 * @return The string. 147 * 148 * @throws ParseException If the object is not of the expected type. 149 */ 150 public static String toString(final Object o) 151 throws ParseException { 152 153 return to(o, String.class); 154 } 155 156 157 /** 158 * Casts an object to a list. 159 * 160 * @param o The object. Must not be {@code null}. 161 * 162 * @return The list. 163 * 164 * @throws ParseException If the object is not of the expected type. 165 */ 166 public static List<?> toList(final Object o) 167 throws ParseException { 168 169 return to(o, List.class); 170 } 171 172 173 /** 174 * Casts an object to a list then returns a string list copy of it 175 * casting each item to a string. 176 * 177 * @param o The object. Must not be {@code null}. 178 * 179 * @return The string list. 180 * 181 * @throws ParseException If the object is not of the expected type. 182 */ 183 public static List<String> toStringList(final Object o) 184 throws ParseException { 185 186 List<String> stringList = new LinkedList<>(); 187 try { 188 for (Object item: toList(o)) { 189 stringList.add((String)item); 190 } 191 } catch (ClassCastException e) { 192 throw new ParseException("Item not a string"); 193 } 194 return stringList; 195 } 196 197 198 /** 199 * Prevents instantiation. 200 */ 201 private JSONUtils() {} 202}