All Downloads are FREE. Search and download functionalities are using the official Maven repository.

pl.wavesoftware.eid.exceptions.Eid Maven / Gradle / Ivy

/*
 * Copyright 2015 Krzysztof Suszyński .
 *
 * 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.
 */
package pl.wavesoftware.eid.exceptions;

import java.io.Serializable;
import static java.lang.Math.abs;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.annotation.Nullable;

/**
 * This class shouldn't be used in any public API or library. It is designed to be used for in-house development
 * of end user applications which will report Bugs in standardized error pages or post them to issue tracker.
 * 

* Exception identifier for all Eid Runtime Exceptions. * * @author Krzysztof Suszyński */ public class Eid implements Serializable { public static final String DEFAULT_FORMAT = "[%s]<%s>"; public static final String DEFAULT_REF_FORMAT = "[%s|%s]<%s>"; public static final String DEFAULT_MESSAGE_FORMAT = "%s => %s"; public static final UniqIdGenerator DEFAULT_UNIQ_ID_GENERATOR = new StdUniqIdGenerator(); private static final long serialVersionUID = -9876432123423401L; private static final int FORMAT_NUM_SPEC = 2; private static final int REF_FORMAT_NUM_SPEC = 3; private static final int MESSAGE_FORMAT_NUM_SPEC = 2; private static String messageFormat = DEFAULT_MESSAGE_FORMAT; private static UniqIdGenerator uniqIdGenerator = DEFAULT_UNIQ_ID_GENERATOR; private static String format = DEFAULT_FORMAT; private static String refFormat = DEFAULT_REF_FORMAT; private final String id; private final String ref; private final String uniq; /** * Constructor * * @param id the exception id, must be unique developer inserted string, from date * @param ref an optional reference */ public Eid(String id, @Nullable String ref) { uniq = uniqIdGenerator.generateUniqId(); this.id = id; this.ref = ref == null ? "" : ref; } /** * Constructor * * @param id the exception id, must be unique developer inserted string, from date */ public Eid(String id) { this(id, null); } /** * Sets a format that will be used for all Eid exceptions when printing a detail message. *

* Format must be non-null and contain two format specifiers "%s" * * @param format a format that will be used, must be non-null and contain two format specifiers "%s" * @return previously used format * @throws IllegalArgumentException if given format hasn't got two format specifiers "%s", or if given format was * null */ @SuppressWarnings("UnusedReturnValue") public static String setMessageFormat(String format) { validateFormat(format, MESSAGE_FORMAT_NUM_SPEC); String oldFormat = Eid.messageFormat; Eid.messageFormat = format; return oldFormat; } /** * Gets actually set message format * * @return actually set message format */ public static String getMessageFormat() { return messageFormat; } /** * Sets the actual unique ID generator that will be used to generate IDs for all Eid objects. It will return previously used * generator. * * @param uniqIdGenerator new instance of unique ID generator * @return a previously used unique ID generator * @throws IllegalArgumentException if given generator was null */ public static UniqIdGenerator setUniqIdGenerator(UniqIdGenerator uniqIdGenerator) { if (uniqIdGenerator == null) { throw new IllegalArgumentException("Unique ID generator can't be null, but given one"); } UniqIdGenerator previous = Eid.uniqIdGenerator; Eid.uniqIdGenerator = uniqIdGenerator; return previous; } /** * Sets the actual format that will be used in {@link #toString()} method. It will return previously used format. * * @param format a format compliant with {@link String#format(String, Object...)} with 2 object arguments * @return a previously used format * @throws IllegalArgumentException if given format hasn't got two format specifiers "%s", or if given format was * null */ public static String setFormat(String format) { validateFormat(format, FORMAT_NUM_SPEC); String previously = Eid.format; Eid.format = format; return previously; } /** * Sets the actual format that will be used in {@link #toString()} method * * @param refFormat a format compliant with {@link String#format(String, Object...)} with 3 object arguments * @return a previously used format * @throws IllegalArgumentException if given format hasn't got tree format specifiers "%s", or if given format was * null */ public static String setRefFormat(String refFormat) { validateFormat(refFormat, REF_FORMAT_NUM_SPEC); String previously = Eid.refFormat; Eid.refFormat = refFormat; return previously; } @Override public String toString() { if ("".equals(ref)) { return String.format(format, id, uniq); } return String.format(refFormat, id, ref, uniq); } /** * Getter for constant Exception ID * * @return ID of exception */ public String getId() { return id; } /** * Get custom ref passed to Exception ID * * @return ID of exception */ public String getRef() { return ref; } /** * Gets unique generated string for this instance of Eid * * @return a unique string */ public String getUniq() { return uniq; } private static void validateFormat(String format, int numSpecifiers) { if (format == null) { throw new IllegalArgumentException("Format can't be null, but just received one"); } List specifiers = new ArrayList(); for (int i = 0; i < numSpecifiers; i++) { specifiers.add(i + "-test-id"); } String formatted = String.format(format, specifiers.toArray()); for (String specifier : specifiers) { if (!formatted.contains(specifier)) { throw new IllegalArgumentException("Given format contains to little format specifiers, " + "expected " + numSpecifiers + " but given \"" + format + "\""); } } } /** * It is used to generate unique ID for each EID object. It's mustn't be secure because it just indicate EID object while * logging. */ public interface UniqIdGenerator { /** * Generates a unique string ID * * @return a generated unique ID */ String generateUniqId(); } private static final class StdUniqIdGenerator implements UniqIdGenerator { private static final int BASE36 = 36; private final Random random; private StdUniqIdGenerator() { this.random = getUnsecuredFastRandom(); } @Override public String generateUniqId() { long first = abs(random.nextLong() + 1); int second = abs(random.nextInt(Integer.MAX_VALUE)); int calc = (int) (first + second); return Integer.toString(calc, BASE36); } @SuppressWarnings("squid:S2245") private Random getUnsecuredFastRandom() { return new Random(System.currentTimeMillis()); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy