/* * Copyright 2002-2016 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 sample.dms; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.support.JdbcDaoSupport; import org.springframework.security.util.FieldUtils; import org.springframework.transaction.support.TransactionSynchronizationManager; import org.springframework.util.Assert; /** * Basic JDBC implementation of {@link DocumentDao}. * * @author Ben Alex */ public class DocumentDaoImpl extends JdbcDaoSupport implements DocumentDao { private static final String INSERT_INTO_DIRECTORY = "insert into directory(directory_name, parent_directory_id) values (?,?)"; private static final String INSERT_INTO_FILE = "insert into file(file_name, content, parent_directory_id) values (?,?,?)"; private static final String SELECT_FROM_DIRECTORY = "select id from directory where parent_directory_id = ?"; private static final String SELECT_FROM_DIRECTORY_NULL = "select id from directory where parent_directory_id is null"; private static final String SELECT_FROM_FILE = "select id, file_name, content, parent_directory_id from file where parent_directory_id = ?"; private static final String SELECT_FROM_DIRECTORY_SINGLE = "select id, directory_name, parent_directory_id from directory where id = ?"; private static final String DELETE_FROM_FILE = "delete from file where id = ?"; private static final String UPDATE_FILE = "update file set content = ? where id = ?"; private static final String SELECT_IDENTITY = "call identity()"; private Long obtainPrimaryKey() { Assert.isTrue(TransactionSynchronizationManager.isSynchronizationActive(), "Transaction must be running"); return getJdbcTemplate().queryForObject(SELECT_IDENTITY, Long.class); } public void create(AbstractElement element) { Assert.notNull(element, "Element required"); Assert.isNull(element.getId(), "Element has previously been saved"); if (element instanceof Directory) { Directory directory = (Directory) element; Long parentId = directory.getParent() == null ? null : directory.getParent() .getId(); getJdbcTemplate().update(INSERT_INTO_DIRECTORY, new Object[] { directory.getName(), parentId }); FieldUtils.setProtectedFieldValue("id", directory, obtainPrimaryKey()); } else if (element instanceof File) { File file = (File) element; Long parentId = file.getParent() == null ? null : file.getParent().getId(); getJdbcTemplate().update(INSERT_INTO_FILE, new Object[] { file.getName(), file.getContent(), parentId }); FieldUtils.setProtectedFieldValue("id", file, obtainPrimaryKey()); } else { throw new IllegalArgumentException("Unsupported AbstractElement"); } } public void delete(File file) { Assert.notNull(file, "File required"); Assert.notNull(file.getId(), "File ID required"); getJdbcTemplate().update(DELETE_FROM_FILE, new Object[] { file.getId() }); } /** Executes recursive SQL as needed to build a full Directory hierarchy of objects */ private Directory getDirectoryWithImmediateParentPopulated(final Long id) { return getJdbcTemplate().queryForObject(SELECT_FROM_DIRECTORY_SINGLE, new Object[] { id }, new RowMapper<Directory>() { public Directory mapRow(ResultSet rs, int rowNumber) throws SQLException { Long parentDirectoryId = new Long(rs .getLong("parent_directory_id")); Directory parentDirectory = Directory.ROOT_DIRECTORY; if (parentDirectoryId != null && !parentDirectoryId.equals(new Long(-1))) { // Need to go and lookup the parent, so do that first parentDirectory = getDirectoryWithImmediateParentPopulated(parentDirectoryId); } Directory directory = new Directory(rs .getString("directory_name"), parentDirectory); FieldUtils.setProtectedFieldValue("id", directory, new Long(rs.getLong("id"))); return directory; } }); } public AbstractElement[] findElements(Directory directory) { Assert.notNull(directory, "Directory required (the ID can be null to refer to root)"); if (directory.getId() == null) { List<Directory> directories = getJdbcTemplate().query( SELECT_FROM_DIRECTORY_NULL, new RowMapper<Directory>() { public Directory mapRow(ResultSet rs, int rowNumber) throws SQLException { return getDirectoryWithImmediateParentPopulated(new Long(rs .getLong("id"))); } }); return (AbstractElement[]) directories.toArray(new AbstractElement[] {}); } List<AbstractElement> directories = getJdbcTemplate().query( SELECT_FROM_DIRECTORY, new Object[] { directory.getId() }, new RowMapper<AbstractElement>() { public Directory mapRow(ResultSet rs, int rowNumber) throws SQLException { return getDirectoryWithImmediateParentPopulated(new Long(rs .getLong("id"))); } }); List<File> files = getJdbcTemplate().query(SELECT_FROM_FILE, new Object[] { directory.getId() }, new RowMapper<File>() { public File mapRow(ResultSet rs, int rowNumber) throws SQLException { Long parentDirectoryId = new Long(rs .getLong("parent_directory_id")); Directory parentDirectory = null; if (parentDirectoryId != null) { parentDirectory = getDirectoryWithImmediateParentPopulated(parentDirectoryId); } File file = new File(rs.getString("file_name"), parentDirectory); FieldUtils.setProtectedFieldValue("id", file, new Long(rs.getLong("id"))); return file; } }); // Add the File elements after the Directory elements directories.addAll(files); return (AbstractElement[]) directories.toArray(new AbstractElement[] {}); } public void update(File file) { Assert.notNull(file, "File required"); Assert.notNull(file.getId(), "File ID required"); getJdbcTemplate().update(UPDATE_FILE, new Object[] { file.getContent(), file.getId() }); } }