001/**
002 * Copyright 2005-2015 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.devtools.jpa.eclipselink.conv.parser.helper.resolver;
017
018import japa.parser.ast.ImportDeclaration;
019import japa.parser.ast.expr.MarkerAnnotationExpr;
020import japa.parser.ast.expr.NameExpr;
021import japa.parser.ast.expr.QualifiedNameExpr;
022import org.apache.logging.log4j.Logger;
023import org.apache.logging.log4j.LogManager;
024import org.apache.ojb.broker.metadata.DescriptorRepository;
025import org.apache.ojb.broker.metadata.FieldDescriptor;
026import org.kuali.rice.devtools.jpa.eclipselink.conv.ojb.OjbUtil;
027import org.kuali.rice.devtools.jpa.eclipselink.conv.parser.helper.NodeData;
028
029import java.util.ArrayList;
030import java.util.Collection;
031import java.util.Collections;
032
033public class LobResolver extends AbstractMappedFieldResolver {
034    private static final Logger LOG = LogManager.getLogger(LobResolver.class);
035
036    public static final String PACKAGE = "javax.persistence";
037    public static final String SIMPLE_NAME = "Lob";
038    private static final Collection<Class<?>> VALID_TYPES;
039    private static final Collection<String> VALID_TYPES_STR;
040    static {
041        Collection<Class<?>> tempClass = new ArrayList<Class<?>>();
042        tempClass.add(String.class);
043        tempClass.add(byte[].class);
044        tempClass.add(Byte[].class);
045        tempClass.add(char[].class);
046        tempClass.add(Character[].class);
047
048        Collection<String> tempClassStr = new ArrayList<String>();
049        for (Class<?> c : tempClass) {
050            tempClassStr.add(c.getName());
051        }
052
053        VALID_TYPES = Collections.unmodifiableCollection(tempClass);
054        VALID_TYPES_STR = Collections.unmodifiableCollection(tempClassStr);
055    }
056
057    public LobResolver(Collection<DescriptorRepository> descriptorRepositories) {
058        super(descriptorRepositories);
059    }
060
061    @Override
062    public String getFullyQualifiedName() {
063        return PACKAGE + "." + SIMPLE_NAME;
064    }
065
066    @Override
067    protected NodeData getAnnotationNodes(String enclosingClass, String fieldName, String mappedClass) {
068        final FieldDescriptor fd = OjbUtil.findFieldDescriptor(mappedClass, fieldName, descriptorRepositories);
069
070        if (fd != null) {
071            final Class<?> fc = ResolverUtil.getType(enclosingClass, fieldName);
072            final String columnType = fd.getColumnType();
073            if (isLob(columnType)) {
074                if (isValidFieldType(fc)) {
075                    return new NodeData(new MarkerAnnotationExpr(new NameExpr(SIMPLE_NAME)),
076                            new ImportDeclaration(new QualifiedNameExpr(new NameExpr(PACKAGE), SIMPLE_NAME), false, false));
077                } else {
078                    LOG.error(ResolverUtil.logMsgForField(enclosingClass, fieldName, mappedClass) + " is not a valid field type for the @Lob annotation, must be one of " + VALID_TYPES_STR);
079                }
080            }
081
082            return null;
083        }
084        return null;
085    }
086
087    private boolean isLob(String columnType) {
088        return "BLOB".equals(columnType) || "CLOB".equals(columnType);
089    }
090
091    private boolean isValidFieldType(Class<?> type) {
092        for (Class<?> c : VALID_TYPES) {
093            if (c.isAssignableFrom(type)) {
094                return true;
095            }
096        }
097        return false;
098    }
099}