org.assertj.assertions.generator.Template.java Source code

Java tutorial

Introduction

Here is the source code for org.assertj.assertions.generator.Template.java

Source

/**
 * 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.
 *
 * Copyright 2012-2015 the original author or authors.
 */
/*
 * 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 org.assertj.assertions.generator;

import org.apache.commons.lang3.CharEncoding;

import com.google.common.io.CharStreams;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLDecoder;

import static com.google.common.io.Closeables.closeQuietly;
import static java.lang.Thread.currentThread;

/**
 * 
 * Holds the template content for assertion generation, can be initialized from a {@link File} or an {@link URL}.
 * <p>
 * Template content example for <code>hasXXX</code> property assertion :
 * 
 * <pre>
 * public ${custom_assertion_class} has${Property}(${propertyType} ${property}) {
 *   // check that actual ${class_to_assert} we want to make assertions on is not null.
 *   isNotNull();
 * 
 *   // we overrides the default error message with a more explicit one
 *   String assertjErrorMessage = format("Expected ${class_to_assert}'s ${property} to be <%s> but was <%s>", ${property}, actual.get${Property}());
 *   
 *   // check
 *   if (!actual.get${Property}().equals(${property})) { throw new AssertionError(assertjErrorMessage); }
 * 
 *   // return the current assertion for method chaining
 *   return this;
 * }
 * </pre>
 * 
 * @author Miguel Bazire
 * @author Joel Costigliola
 */
public class Template {

    private String content;
    private final Type type;

    /**
     * Creates a new </code>{@link Template}</code> from the given content.
     * 
     * @param templateContent the template content
     */
    public Template(Type type, String templateContent) {
        this.content = templateContent;
        this.type = type;
    }

    /**
     * Creates a new </code>{@link Template}</code> from the content of the given {@link URL}.
     * 
     * @param url the {@link URL} to read to set the content of the {@link Template}
     * @throws RuntimeException if we fail to read the {@link URL} content
     */
    public Template(Type type, URL url) {
        this.type = type;
        try {
            File urlFile = new File(URLDecoder.decode(url.getFile(), CharEncoding.UTF_8));
            if (!urlFile.isFile()) {
                throw new RuntimeException(
                        "Failed to read template from an URL which is not a file, URL was :" + url);
            }
            // TODO : read from file directly ?
            content = readContentThenClose(url.openStream());
        } catch (IOException e) {
            throw new RuntimeException("Failed to read template from " + url, e);
        }
    }

    /**
     * Creates a new </code>{@link Template}</code> from the content of the given {@link File} searched in the classpath.
     * 
     * @param file the {@link File} to read to set the content of the {@link Template}
     * @throws RuntimeException if we fail to read the {@link File} content
     */
    public Template(Type type, File file) {
        this.type = type;
        // don't use file.toURI().toURL() to call Template based URL constructor :
        // it does not load resources from classpath.
        String path = file.getPath();
        try {
            // TODO see if we can get rid of this and only call readTemplateFile(file, path.replace('\\', '/'));
            this.content = readTemplateFile(file, file.getPath());
        } catch (RuntimeException e) {
            // try to read file again but from assert-assertions-generator jar
            // => need to replace file system separator by '/' because it relies o
            this.content = readTemplateFile(file, path.replace('\\', '/'));
        }
    }

    private String readTemplateFile(File file, String path) {
        try {
            InputStream inputStream = currentThread().getContextClassLoader().getResourceAsStream(path);
            return readContentThenClose(inputStream);
        } catch (Exception e) {
            throw new RuntimeException("Failed to read template from file " + file, e);
        }
    }

    public String getContent() {
        return content;
    }

    public Type getType() {
        return type;
    }

    private String readContentThenClose(InputStream input) throws IOException {
        InputStreamReader reader = new InputStreamReader(input);
        try {
            return CharStreams.toString(reader);
        } finally {
            closeQuietly(input);
            closeQuietly(reader);
        }
    }

    @Override
    public boolean equals(Object o) {
        if (this == o)
            return true;
        if (o == null || getClass() != o.getClass())
            return false;
        Template template = (Template) o;
        return type != template.type ? false : true;
    }

    @Override
    public int hashCode() {
        return type.hashCode();
    }

    public enum Type {
        // @format:off
        IS, IS_WITHOUT_NEGATION, IS_WRAPPER, IS_WRAPPER_WITHOUT_NEGATION, HAS, HAS_FOR_ARRAY, HAS_FOR_ITERABLE, HAS_FOR_PRIMITIVE, HAS_FOR_PRIMITIVE_WRAPPER, HAS_FOR_REAL_NUMBER, HAS_FOR_REAL_NUMBER_WRAPPER, HAS_FOR_WHOLE_NUMBER, HAS_FOR_WHOLE_NUMBER_WRAPPER, HAS_FOR_CHAR, HAS_FOR_CHARACTER, ASSERT_CLASS, HIERARCHICAL_ASSERT_CLASS, ABSTRACT_ASSERT_CLASS, ASSERTIONS_ENTRY_POINT_CLASS, ASSERTION_ENTRY_POINT, SOFT_ASSERTIONS_ENTRY_POINT_CLASS, JUNIT_SOFT_ASSERTIONS_ENTRY_POINT_CLASS, SOFT_ENTRY_POINT_METHOD_ASSERTION, BDD_ASSERTIONS_ENTRY_POINT_CLASS, BDD_ENTRY_POINT_METHOD_ASSERTION, BDD_SOFT_ASSERTIONS_ENTRY_POINT_CLASS, BDD_SOFT_ENTRY_POINT_METHOD_ASSERTION, JUNIT_BDD_SOFT_ASSERTIONS_ENTRY_POINT_CLASS, AUTO_CLOSEABLE_SOFT_ASSERTIONS_ENTRY_POINT_CLASS, AUTO_CLOSEABLE_BDD_SOFT_ASSERTIONS_ENTRY_POINT_CLASS
        // @format:on
    }

}