/*
 * Copyright 2007 Joachim Grueneis
 *
 * 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.castor.xml;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * JavaNaming is a service which collects all methods that are related to
 * create (modify) Java names. E.g. convert from XML name to Java name,
 * get a Java member name or such. These rules can be exchanged by a different
 * implementation to get a different naming style for e.g. JAXB.
 * 
 * @author <a href="mailto:jgrueneis_at_gmail_dot_com">Joachim Grueneis</a>
 * @version $Id: JavaNaming.java 7390 2008-01-25 15:59:42Z jgrueneis $
 */
public interface JavaNaming {
    /** Add methods start with: add. */
    public static final String METHOD_PREFIX_ADD = "add";

    /** Get methods start with: get. */
    public static final String METHOD_PREFIX_GET = "get";

    /** Is methods start with: is. */
    public static final String METHOD_PREFIX_IS = "is";

    /** Set methods start with: set. */
    public static final String METHOD_PREFIX_SET = "set";

    /** Create methods start with: create. */
    public static final String METHOD_PREFIX_CREATE = "create";
    
    /** The underscore field prefix. */
    public static final char FIELD_UNDERSCORE_PREFIX = '_';

    /**
     * Returns true if the given String is a Java keyword which will cause a
     * problem when used as a variable name.
     * 
     * @param name The name to check.
     * @return true if it is a keyword.
     */
    boolean isKeyword(String name);
    
    /**
     * Returns true if the given String matches the production of a valid Java
     * identifier.
     * 
     * @param string The String to check the production of.
     * @return true if the given String matches the production of a valid Java
     *         name, otherwise false.
     */
    boolean isValidJavaIdentifier(String string);
    
    /**
     * Cuts away a leading namespace prefix (if there is one in place).
     * 
     * @param name The XML name to convert to a Java name.
     * @return A name which follows Java naming conventions.
     */
    String toJavaClassName(String name);
    
    /**
     * Appends a leading '_' and converts the given name to a java name.
     * 
     * @param name the XML name to convert.
     * @return A Java member name starting with a leading '_'.
     */
    String toJavaMemberName(String name);
    
    /**
     * Appends a leading '_' and converts the given name to a java name.
     * 
     * @param name The XML name to convert.
     * @param useKeywordSubstitutions Set to true to turn on keyword substitution.
     * @return A Java member name starting with a leading '_'.
     */
    String toJavaMemberName(String name, boolean useKeywordSubstitutions);
    
    /**
     * Checks if the given package name is valid or not. Empty package names
     * are considered valid!
     * 
     * @param packageName Name of package as String with periods.
     * @return true if package name is valid.
     */
    boolean isValidPackageName(String packageName);
    
    /**
     * Converts the given Package name to it's corresponding Path. The path will
     * be a relative path.
     * 
     * @param packageName The package name to convert.
     * @return A String containing the resulting patch.
     */
    String packageToPath(String packageName);
    
    /**
     * Qualifies the given <code>fileName</code> with the given
     * <code>packageName</code> and returns the resulting file path.<br>
     * If <code>packageName</code> is <code>null</code> or a zero-length
     * String, this method will return <code>fileName</code>.<br>
     * 
     * @param fileName The file name to be qualified.
     * @param packageName The package name to be used for qualifying.
     * @return The qualified file path.
     */
    String getQualifiedFileName(String fileName, String packageName);
    
    /**
     * Gets the class name without package part.
     * 
     * @param clazz The class to retrieve the name from
     * @return the class name without package part or null
     */
    String getClassName(Class clazz);
    
    /**
     * Gets the package name of the given class name.
     * 
     * @param className The class name to retrieve the package name from.
     * @return The package name or the empty String if <code>className</code>
     *         is <code>null</code> or does not contain a package.
     */
    String getPackageName(String className);

    /**
     * Extracts the filed name part from the methods name. Mostly it cuts
     * away the method prefix.
     * 
     * @param method The Method to process.
     * @return The extracted field name.
     */
    String extractFieldNameFromMethod(Method method);
    
    /**
     * Extracts the field name part from the Field. Mostly it cuts away
     * prefixes like '_'.
     * 
     * @param field the Field to process
     * @return The extracted field name.
     */
    String extractFieldNameFromField(Field field);
    
    /**
     * Checks if the given method is a set method.
     * 
     * @param method The Method to check
     * @return true if it is a set method
     */
    boolean isSetMethod(Method method);
    /**
     * Checks if the given method is a create method.
     * 
     * @param method The Method to check.
     * @return true if it is a create method.
     */
    boolean isCreateMethod(Method method);
    
    /**
     * Checks if the given method is a get method.
     * 
     * @param method The Method to check.
     * @return true if it is a get method.
     */
    boolean isGetMethod(Method method);
    
    /**
     * Checks if the given method is an is method.
     * 
     * @param method The Method to check.
     * @return true if it is an is method.
     */
    boolean isIsMethod(Method method);
    
    /**
     * Checks if the given method is an add method.
     * 
     * @param method The Method to check.
     * @return true if it is an add method.
     */
    boolean isAddMethod(Method method);
    /**
     * Generates the name of an add method for the given field name.
     * 
     * @param fieldName The field name to generate a method name for.
     * @return The generated add method name.
     */
    String getAddMethodNameForField(String fieldName);
    
    /**
     * Generates the name of a set method for the given field name.
     * 
     * @param fieldName The field name to generate a method name for.
     * @return The generated set method name.
     */
    String getSetMethodNameForField(String fieldName);
    
    /**
     * Generates the name of a get method for the given field name.
     * 
     * @param fieldName The field name to generate a method name for.
     * @return The generated get method name.
     */
    String getGetMethodNameForField(String fieldName);
    
    /**
     * Generates the name of an is method for the given field name.
     * 
     * @param fieldName The field name to generate a method name for.
     * @return The generated is method name.
     */
    String getIsMethodNameForField(String fieldName);
    
    /**
     * Generates the name of a create method for the given field name.
     * 
     * @param fieldName The field name to generate a method name for.
     * @return The generated create method name.
     */
    String getCreateMethodNameForField(String fieldName);
}