/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 org.schemarepo; import java.io.IOException; import java.io.StringWriter; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Properties; /** * {@link RepositoryUtil} contains static helper methods for the * org.schemarepo package. * <p> * {@link #subjectsToString(Iterable)} and * {@link #subjectNamesFromString(String)} can be used to encode * subjects to string format. <br/> * {@link #schemasToString(Iterable)} and {@link #schemasFromString(String)} can * be used to encode schemas to string format. * </p> * <p> * These formats simply delimit items by the newline character and can be used * for human readable output. The RESTRepository uses this format to encode * subjects and schemas over HTTP. Subject names are forbidden from containing * whitespace. Schemas have their whitespace removed prior to use in the * Repository. * </p> */ public final class RepositoryUtil { private RepositoryUtil() { } /** * Encode {@link Subject}s into a {@link String} for use by * {@link #subjectNamesFromString(String)} * * @param subjects * the Subject objects to encode * @return The {@link Subject} objects encoded as a String */ public static String subjectsToString(Iterable<Subject> subjects) { StringBuilder sb = new StringBuilder(); for (Subject s : subjects) { sb.append(s.getName()).append("\n"); } return sb.toString(); } /** * Decode a string created by {@link #subjectsToString(Iterable)} * * @param str * The String to decode * @return an {@link java.lang.Iterable} of {@link Subject} */ public static Iterable<String> subjectNamesFromString(String str) { List<String> subjects = new ArrayList<String>(); if (str != null && !str.isEmpty()) { String[] strs = str.split("\n"); for (String s : strs) { subjects.add(s); } } return subjects; } /** * Encode {@link SchemaEntry} objects into a {@link String} for use by * {@link #schemasFromString(String)} * * @param allEntries * the SchemaEntry objects to encode * @return The {@link SchemaEntry} objects encoded as a String */ public static String schemasToString(Iterable<SchemaEntry> allEntries) { StringBuilder sb = new StringBuilder(); boolean scheamWithNewLine = false; for (SchemaEntry s : allEntries) { if (s.getSchema().contains("\n")) { scheamWithNewLine = true; } sb.append(s.toString()).append("\n"); } if (scheamWithNewLine) { return new StringBuilder() .append(MessageStrings.SCHEMA_WITH_NEWLINE_ERROR) .append(sb).toString(); } else { return sb.toString(); } } /** * Decode a string created by {@link #schemasToString(Iterable)} * * @param str * The String to decode * @return An {@link java.lang.Iterable} of {@link SchemaEntry} */ public static Iterable<SchemaEntry> schemasFromString(String str) { List<SchemaEntry> schemas = new ArrayList<SchemaEntry>(); if (str != null && !str.isEmpty()) { String[] strs = str.split("\n"); for (String s : strs) { schemas.add(new SchemaEntry(s)); } } return schemas; } /** * Throws IllegalArgumentException if the string provided is null, or empty. */ public static void validateSchemaOrSubject(String val) { if (null == val || val.isEmpty()) { throw new IllegalArgumentException( "Provided string is null or empty: '" + val + "'"); } } /** * Returns an immutable Map<String, String> from the properties provided. * Includes any default values that exist in the properties. */ public static SubjectConfig configFromProperties(Properties props) { HashMap<String, String> propData = new HashMap<String, String>(); for (String key :props.stringPropertyNames()) { propData.put(key, props.getProperty(key)); } return new SubjectConfig.Builder().set(propData).build(); } /** temporary until we have decided how to deal with null configs or create a SubjectConfig class **/ public static SubjectConfig safeConfig(SubjectConfig config) { if (null == config) { return SubjectConfig.emptyConfig(); } else { return config; } } /** * Helper method for splitting a string by a delimiter with * java.util.String.split(). * Omits empty values. * @param toSplit The string to split. If null, an empty * String[] is returned * @return A String[] containing the non-empty values resulting * from the split. Does not return null. */ public static List<String> commaSplit(String toSplit) { if (toSplit == null) { return Collections.emptyList(); } ArrayList<String> list = new ArrayList<String>(); for(String s : toSplit.split(",")) { s = s.trim(); if (!s.isEmpty()) { list.add(s); } } return list; } public static String commaJoin(Collection<String> strings) { StringBuilder sb = new StringBuilder(); for(String s : strings) { sb.append(s).append(','); } // trim the trailing comma if (sb.length() > 0) return sb.substring(0,sb.length()-1); return sb.toString(); } /** * Converts properties to string representation * @param props * @param comment optional comment (can be null) * @return String (standard key=value format) */ public static String propertiesToString(Properties props, String comment) { StringWriter writer = new StringWriter(); try { props.store(writer, comment); } catch (IOException e) { // never happens for StringWriter } return writer.toString(); } }