/* * Copyright (c) 2010-2013 Evolveum * * 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 com.evolveum.midpoint.repo.sql.util; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import org.apache.commons.lang.StringUtils; import org.hibernate.cfg.EJB3NamingStrategy; /** * @author lazyman */ public class MidPointNamingStrategy extends EJB3NamingStrategy { private static final Trace LOGGER = TraceManager.getTrace(MidPointNamingStrategy.class); private static final int MAX_LENGTH = 30; @Override public String columnName(String columnName) { String rv = super.columnName(columnName); LOGGER.trace("columnName {} to {}", columnName, rv); return rv; } @Override public String joinKeyColumnName(String joinedColumn, String joinedTable) { String rv = super.joinKeyColumnName(joinedColumn, joinedTable); LOGGER.trace("joinKeyColumnName joinedColumn={}, joinedTable={} to {}", joinedColumn, joinedTable, rv); return rv; } @Override public String classToTableName(String className) { String name = className.substring(1); //change camel case to underscore delimited name = name.replaceAll(String.format("%s|%s|%s", "(?<=[A-Z])(?=[A-Z][a-z])", "(?<=[^A-Z])(?=[A-Z])", "(?<=[A-Za-z])(?=[^A-Za-z])" ), "_"); String result = "m_" + name.toLowerCase(); result = fixLength(result); LOGGER.trace("classToTableName {} to {}", className, result); return result; } @Override public String logicalColumnName(String columnName, String propertyName) { String result; if (StringUtils.isNotEmpty(columnName)) { result = columnName; } else { if (propertyName.startsWith("credentials.") || propertyName.startsWith("activation.")) { //credentials and activation are embedded and doesn't need to be qualified result = super.propertyToColumnName(propertyName); } else { result = propertyName.replaceAll("\\.", "_"); } } result = fixLength(result); LOGGER.trace("logicalColumnName {} {} to {}", columnName, propertyName, result); return result; } @Override public String propertyToColumnName(String propertyName) { String result = propertyName.replaceAll("\\.", "_"); if (propertyName.contains("&&")) { result = super.propertyToColumnName(propertyName); } else if (propertyName.startsWith("credentials.") || propertyName.startsWith("activation.")) { //credentials and activation are embedded and doesn't need to be qualified result = super.propertyToColumnName(propertyName); } result = fixLength(result); if (LOGGER.isTraceEnabled()) { LOGGER.trace("propertyToColumnName {} to {} (original: {})", propertyName, result, super.propertyToColumnName(propertyName)); } return result; } @Override public String foreignKeyColumnName(String propertyName, String propertyEntityName, String propertyTableName, String referencedColumnName) { // TODO fixme BRUTAL HACK -- we are not able to eliminate columns like 'ownerRefCampaign_targetOid' from the schema (even with @AttributeOverride/@AssociationOverride) if ("ownerRefCampaign.target".equals(propertyName) || "ownerRefDefinition.target".equals(propertyName) || "ownerRefTask.target".equals(propertyName)) { propertyName = "ownerRef.target"; } String header = propertyName != null ? propertyName.replaceAll("\\.", "_") : propertyTableName; String result; if (header.endsWith("target") && referencedColumnName.equals("oid")) { result = header + "Oid"; // to keep compatibility with existing mappings } else { result = header + "_" + referencedColumnName; } result = fixLength(result); if (LOGGER.isTraceEnabled()) { LOGGER.trace("foreignKeyColumnName for propertyName={}, propertyEntityName={}, propertyTableName={}, " + "referencedColumnName={} returns {} (original: {})", propertyName, propertyEntityName, propertyTableName, referencedColumnName, result, super.foreignKeyColumnName(propertyName, propertyEntityName, propertyTableName, referencedColumnName)); } return result; } private String fixLength(String input) { if (input == null || input.length() <= MAX_LENGTH) { return input; } String result = input; String[] array = input.split("_"); for (int i = 0; i < array.length; i++) { int length = array[i].length(); String lengthStr = Integer.toString(length); if (length < lengthStr.length()) { continue; } array[i] = array[i].charAt(0) + lengthStr; result = StringUtils.join(array, "_"); if (result.length() < MAX_LENGTH) { break; } } return result; } }