/** * Copyright (c) 2004-2011 Wang Jinbao(Julian Wong), http://www.ralasafe.com * Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php */ package org.ralasafe.userType; import java.io.ByteArrayInputStream; import java.io.FileReader; import java.sql.Connection; import java.sql.SQLException; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.ralasafe.EntityExistException; import org.ralasafe.Factory; import org.ralasafe.RalasafeException; import org.ralasafe.application.Application; import org.ralasafe.application.ApplicationUserType; import org.ralasafe.db.DBLevelException; import org.ralasafe.db.DBPower; import org.ralasafe.db.FieldWhereElement; import org.ralasafe.db.JavaBeanColumnAdapter; import org.ralasafe.db.JavaBeanObjectNewer; import org.ralasafe.db.SingleValueComparator; import org.ralasafe.db.Table; import org.ralasafe.db.TableNewer; import org.ralasafe.db.TableUpdator; import org.ralasafe.db.impl.TableDeletorImpl; import org.ralasafe.db.impl.TableSaverImpl; import org.ralasafe.db.impl.TableSelectorImpl; import org.ralasafe.db.impl.TableUpdatorImpl; import org.ralasafe.metadata.user.UserMetadata; import org.ralasafe.metadata.user.UserMetadataParser; import org.ralasafe.util.DBUtil; import org.ralasafe.util.StringUtil; public class UserTypeManagerImpl implements UserTypeManager { private static Log logger=LogFactory.getLog( UserTypeManagerImpl.class ); /** * UserType cache store */ Map userTypeMap = new HashMap(); private boolean changed=true; private Table table; private TableSelectorImpl selector; private TableSaverImpl saver; private TableUpdator updator; private TableDeletorImpl deletor; private FieldWhereElement nameWhereEmt; private TableDeletorImpl applicationUserTypeDeletor; private FieldWhereElement userTypeNameAppUserTypeTableWhereEmt; public UserTypeManagerImpl() { initUserTypeTableInfo(); initApplicationUserTypeTableInfo(); } private void initApplicationUserTypeTableInfo() { TableNewer newer = new TableNewer(); newer.setTableName( "applicationusertype" ); newer.setColumnNames(new String[] { "appName", "userTypeName","userMetadataStr" }); newer.setIdColumnNames(new String[] { "appName", "userTypeName" } ); //newer.setUniqueColumnNames(new String[] { "name" }); newer.setMappingClass(ApplicationUserType.class.getName()); newer.put("appName", new JavaBeanColumnAdapter("appName", "java.lang.String")); newer.put("userTypeName", new JavaBeanColumnAdapter("userTypeName", "java.lang.String")); newer.put("userMetadataStr", new JavaBeanColumnAdapter("userMetadataStr", "java.lang.String")); newer.setId(DBPower.getTableId(null, newer.getTableName())); Table appUserTypeTable = newer.getTable(); applicationUserTypeDeletor = new TableDeletorImpl(); applicationUserTypeDeletor.setTable(appUserTypeTable); userTypeNameAppUserTypeTableWhereEmt=new FieldWhereElement(); userTypeNameAppUserTypeTableWhereEmt.setColumn( appUserTypeTable.getColumns()[1] ); userTypeNameAppUserTypeTableWhereEmt.setCompartor( SingleValueComparator.EQUAL ); userTypeNameAppUserTypeTableWhereEmt.setContextValue( true ); } private void initUserTypeTableInfo() { TableNewer newer = new TableNewer(); newer.setTableName( "usertype" ); newer.setColumnNames(new String[] { "name", "description","userMetadataXML" }); newer.setIdColumnNames(new String[] { "name" }); //newer.setUniqueColumnNames(new String[] { "name" }); newer.setMappingClass(UserType.class.getName()); newer.put("name", new JavaBeanColumnAdapter("name", "java.lang.String")); newer.put("description", new JavaBeanColumnAdapter("desc", "java.lang.String")); newer.put("userMetadataXML", new JavaBeanColumnAdapter("userMetadataXML", "java.lang.String")); newer.setId(DBPower.getTableId(null, newer.getTableName())); table = newer.getTable(); selector = new TableSelectorImpl(); selector.setObjectNewer(new JavaBeanObjectNewer(newer.getMappingClass())); saver = new TableSaverImpl(); updator = new TableUpdatorImpl(); deletor = new TableDeletorImpl(); selector.setTable(table); saver.setTable(table); updator.setTable(table); deletor.setTable(table); nameWhereEmt=new FieldWhereElement(); nameWhereEmt.setColumn( table.getColumns()[0] ); nameWhereEmt.setCompartor( SingleValueComparator.EQUAL ); nameWhereEmt.setContextValue( true ); } private synchronized void loadIntoMemory() { if( !changed ) { return; } Collection allUserTypes=selector.select( null, null ); userTypeMap.clear(); for( Iterator iter=allUserTypes.iterator(); iter.hasNext(); ) { UserType userType=(UserType) iter.next(); extractUserMetadata( userType ); userTypeMap.put( userType.getName(), userType ); } changed=false; } private void preModify( UserType userType ) { String xml = getUserMetadataXML(userType); if( xml.length()>=1000&&xml.length()<=2000 ) { xml=StringUtils.rightPad( xml, 4000-xml.length() ); } userType.setUserMetadataXML(xml); } public void addUserType(UserType userType) throws EntityExistException { loadIntoMemory(); // check duplicated name if( userTypeMap.keySet().contains( userType.getName() ) ) { throw new EntityExistException("The name '" + userType.getName() + "' exists already."); } preModify( userType ); extractUserMetadata( userType ); saver.save( userType ); changed=true; } private String getUserMetadataXML(UserType userType) { int ch = 0; StringBuffer buf = new StringBuffer(); try { FileReader reader = new FileReader(userType.getSrcFile()); while ((ch = reader.read()) != -1) { buf.append((char) ch); } reader.close(); return buf.toString(); } catch (Exception e) { throw new RalasafeException(e); } } public void deleteUserType(String name) { loadIntoMemory(); Collection applications = getApplications(name); Connection conn=null; boolean autoCommit=true; try { conn=DBPower.getConnection( table.getId() ); autoCommit=conn.getAutoCommit(); conn.setAutoCommit( false ); // drop application's user-role tables for(Iterator itr=applications.iterator();itr.hasNext();) { Application application = (Application) itr.next(); String dropSql=DBUtil.userRoleTableDropSql(application.getName(), name); try { DBUtil.exec(conn, dropSql); } catch( SQLException e ) { logger.error( "Failed to delete table: " + dropSql ); } } // delete app-usertype relationship ApplicationUserType appUserTypeHint=new ApplicationUserType(); appUserTypeHint.setUserTypeName( name ); applicationUserTypeDeletor.delete( conn, userTypeNameAppUserTypeTableWhereEmt, appUserTypeHint ); // delete UserType UserType userTypeHint=new UserType(); userTypeHint.setName( name ); deletor.deleteByIdColumns( conn, userTypeHint ); conn.commit(); } catch( SQLException e ) { DBUtil.rollback( conn ); throw new DBLevelException( e ); } finally { DBUtil.setCommitMode( conn, autoCommit ); DBUtil.close( conn ); } //userTypeMap.remove(name); changed=true; // notify Factory Factory.userTypeChanged(name); } public Collection getAllUserTypes() { loadIntoMemory(); return userTypeMap.values(); } public UserType getUserType(String name) { loadIntoMemory(); return (UserType) userTypeMap.get(name); } /** * Extract UserMetadata from userType's xml definition, * and validate the infomation * @param userType */ private void extractUserMetadata(UserType userType) { // parse if (userType.getUserMetadataXML() != null) { UserMetadataParser parser = new UserMetadataParser(); UserMetadata userMetadata=parser.parse(new ByteArrayInputStream( userType.getUserMetadataXML().getBytes())); String validInfo=userMetadata.getValidInfo(); if( !StringUtil.isEmpty( validInfo ) ) { System.out.println( "Error: user metadata is invalid! name=" + userType.getName() ); System.out.println( validInfo ); System.out.println( "userMetadataStr=" ); System.out.println( userType.getUserMetadataXML() ); throw new RalasafeException( "User metadata is invalid! " + validInfo ); } userType.setUserMetadata(userMetadata); } } public void updateUserType(UserType userType) { preModify( userType ); extractUserMetadata( userType ); try { updator.updateByIdColumns( userType ); } catch( EntityExistException e ) { throw new DBLevelException( e ); } changed=true; // notify Factory Factory.userTypeChanged(userType.getName()); } public Collection getApplications(String userTypeName) { loadIntoMemory(); Set applications = new HashSet(); Iterator appItr = Factory.getApplicationManager().getAllApplications() .iterator(); while (appItr.hasNext()) { Application application = (Application) appItr.next(); Iterator itr = application.getUserTypes().iterator(); while (itr.hasNext()) { UserType userType = (UserType) itr.next(); if (userType.getName().equals(userTypeName)) applications.add(application); } } return applications; } public UserType getUserTypeCopy(String name) { loadIntoMemory(); UserType cacheOne=(UserType) userTypeMap.get( name ); if( cacheOne==null ) { return null; } else { UserType copy=new UserType(); copy.setDesc( cacheOne.getDesc() ); copy.setName( cacheOne.getName() ); copy.setSrcFile( cacheOne.getSrcFile() ); copy.setUserMetadataXML( cacheOne.getUserMetadataXML() ); extractUserMetadata( copy ); return copy; } } }