001: package com.sun.portal.app.filesharing.repo;
002:
003: import com.sun.portal.app.filesharing.util.*;
004: import com.sun.portal.app.filesharing.faces.FolderBean;
005:
006: import java.io.*;
007: import java.util.logging.Logger;
008: import java.util.logging.Level;
009: import java.util.ArrayList;
010: import java.util.List;
011: import java.sql.*;
012:
013: /**
014: * @author Alejandro Abdelnur
015: */
016: public class JdbcRepository implements Repository {
017:
018: private static Logger _logger = LogUtils.getInstance().getLogger(
019: FolderBean.class.getName());
020:
021: private String _datasource;
022: private String _repositoryId;
023: private String _uid = null;
024: private static final String OP_WRITE = "WRITE";
025: private static final String OP_READ = "READ";
026: private boolean isOwner = false;
027:
028: public JdbcRepository(String datasource) throws RepoException {
029: this (datasource, null, null);
030: }
031:
032: public JdbcRepository(String datasource, String repositoryId,
033: String uid) throws RepoException {
034: _datasource = datasource;
035: _repositoryId = repositoryId;
036: _uid = uid;
037: if (_logger.isLoggable(Level.FINER)) {
038: _logger.log(Level.FINER, "repository.<init> datasource:"
039: + _datasource + " _repository:" + _repositoryId);
040: }
041: }
042:
043: private void addFile(RepoItem file, InputStream is, boolean replace)
044: throws RepoException, IOException {
045: SQLExecutor sqlExec = new SQLExecutor(_datasource);
046: AddFileTask aft = new AddFileTask(_repositoryId, file, is,
047: replace);
048: try {
049: sqlExec.execute(aft);
050: } catch (SQLException ex) {
051: throw new RepoException("F013", "Could not create file",
052: file, ex);
053: }
054: }
055:
056: private static class AddFileTask implements SQLTask {
057: private String _repositoryId;
058: private RepoItem _repoItem;
059: private InputStream _is;
060: private boolean _replace;
061:
062: public AddFileTask(String repositoryId, RepoItem file,
063: InputStream is, boolean replace) {
064: _repositoryId = repositoryId;
065: _repoItem = file;
066: _is = is;
067: _replace = replace;
068: }
069:
070: private final static String INSERT_STR = "insert into filesystem "
071: + "(repositoryId,directory,name,isDir,creator,created,modified,datasize,data) "
072: + "values(?,?,?,0,?,?,?,?,?)";
073:
074: public void run(Connection conn) throws SQLException,
075: RepoException {
076: conn.setAutoCommit(false);
077: if (_replace) {
078: DeleteFileTask dft = new DeleteFileTask(_repositoryId,
079: _repoItem, false, false);
080: dft.runWoCommit(conn);
081: }
082: PreparedStatement ps = conn.prepareStatement(INSERT_STR);
083: ps.setString(1, _repositoryId);
084: ps.setString(2, _repoItem.getParent().getPath());
085: ps.setString(3, _repoItem.getName());
086: ps.setString(4, _repoItem.getCreator());
087: long time = System.currentTimeMillis();
088: ps.setLong(5, time);
089: ps.setLong(6, time); // if replacing creation time should be kept from previous entry
090: ps.setInt(7, (int) _repoItem.getLength());
091: ps.setBinaryStream(8, _is, (int) _repoItem.getLength());
092: ps.execute();
093: ps.close();
094: conn.commit();
095: }
096:
097: }
098:
099: public void addFile(RepoItem file, InputStream is)
100: throws RepoException, IOException {
101: if (_logger.isLoggable(Level.FINER)) {
102: _logger.log(Level.FINER, "repository.addFile("
103: + file.getPath() + ")");
104: }
105: addFile(file, is, false);
106: }
107:
108: public void replaceFile(RepoItem file, InputStream stream)
109: throws RepoException, IOException {
110: if (_logger.isLoggable(Level.FINER)) {
111: _logger.log(Level.FINER, "repository.replaceFile("
112: + file.getPath() + ")");
113: }
114: accessCheck(OP_WRITE, file);
115: addFile(file, stream, true);
116: }
117:
118: public InputStream getFile(RepoItem file) throws RepoException,
119: IOException {
120: if (_logger.isLoggable(Level.FINER)) {
121: _logger.log(Level.FINER, "repository.getFile(): "
122: + file.getPath());
123: }
124: SQLExecutor sqlExec = new SQLExecutor(_datasource);
125: GetFileTask gft = new GetFileTask(_repositoryId, file);
126: try {
127: sqlExec.execute(gft);
128: } catch (SQLException ex) {
129: throw new RepoException("F020", "Could not get file", file,
130: ex);
131: }
132: return gft.getInputStream();
133: }
134:
135: private static class GetFileTask implements SQLTask {
136: private String _repositoryId;
137: private RepoItem _repoItem;
138: private InputStream _is;
139:
140: public GetFileTask(String repositoryId, RepoItem file) {
141: _repositoryId = repositoryId;
142: _repoItem = file;
143: }
144:
145: public InputStream getInputStream() {
146: return _is;
147: }
148:
149: private final static String SELECT_STR = "select datasize,data from filesystem where repositoryId=? and directory=? and name=?";
150:
151: public void run(Connection conn) throws SQLException,
152: RepoException {
153: PreparedStatement ps = conn.prepareStatement(SELECT_STR);
154: ps.setString(1, _repositoryId);
155: ps.setString(2, _repoItem.getParent().getPath());
156: ps.setString(3, _repoItem.getName());
157: ResultSet rs = ps.executeQuery();
158: if (rs.next()) {
159: int size = rs.getInt(1);
160: InputStream is = rs.getBinaryStream(2);
161: ByteArrayOutputStream baos = new ByteArrayOutputStream(
162: size);
163: try {
164: IOUtils.copyStream(is, baos);
165: baos.close();
166: _is = new ByteArrayInputStream(baos.toByteArray());
167: } catch (IOException ex) {
168: _logger.log(Level.WARNING, "repository.getFile("
169: + _repoItem.getPath() + ")", ex);
170: throw new RepoException("F022",
171: "Could not read data stream", _repoItem, ex);
172: }
173: }
174: ps.close();
175: }
176:
177: }
178:
179: protected void setIsOnwer(boolean value) {
180: this .isOwner = value;
181: }
182:
183: private void accessCheck(String op, RepoItem file)
184: throws RepoException {
185: if (isOwner
186: || (_uid != null && _uid
187: .equals(RepoFactory.REPO_OWNER_PROXY)))
188: return;
189: if (op.equals(OP_WRITE)) {
190: if (!file.isFromRepo()) {
191: file = getItemInfo(file);
192: }
193: String creator = file.getCreator();
194: if (_uid == null || creator == null
195: || !_uid.equalsIgnoreCase(creator)) {
196: throw new RepoException(
197: "F201",
198: "You don't have the right to perform this operation",
199: file);
200: }
201: }
202: }
203:
204: public void deleteFile(RepoItem file) throws RepoException {
205: if (_logger.isLoggable(Level.FINER)) {
206: _logger.log(Level.FINER, "repository.deleteFile("
207: + file.getPath() + ")");
208: }
209: accessCheck(OP_WRITE, file);
210: SQLExecutor sqlExec = new SQLExecutor(_datasource);
211: DeleteFileTask dft = new DeleteFileTask(_repositoryId, file,
212: false, false);
213: try {
214: sqlExec.execute(dft);
215: } catch (SQLException ex) {
216: throw new RepoException("F032",
217: "File could not be deleted", file, ex);
218: }
219: }
220:
221: private static class DeleteFileTask implements SQLTask {
222: private String _repositoryId;
223: private RepoItem _repoItem;
224: private boolean _isFolder;
225: private boolean _deleteNotEmpty;
226:
227: public DeleteFileTask(String repositoryId, RepoItem file,
228: boolean isFolder, boolean deleteNotEmpty) {
229: _repositoryId = repositoryId;
230: _repoItem = file;
231: _isFolder = isFolder;
232: _deleteNotEmpty = deleteNotEmpty;
233: }
234:
235: private final static String DELETE_FILE_STR = "delete from filesystem where "
236: + "repositoryId=? and directory=? and name=? and isDir=0";
237:
238: private final static String COUNT_STR = "select count(*) from filesystem where "
239: + "repositoryId=? and directory=?";
240:
241: private final static String DELETE_FOLDER_STR = "delete from filesystem where "
242: + "repositoryId=? and ((directory=? and name=?) or "
243: + "directory=? or directory like ? )";
244: private final static String DELETE_REPO_STR = "delete from filesystem where "
245: + "repositoryId=?";
246:
247: public void run(Connection conn) throws SQLException,
248: RepoException {
249: conn.setAutoCommit(false);
250: runWoCommit(conn);
251: conn.commit();
252: }
253:
254: public void runWoCommit(Connection conn) throws SQLException,
255: RepoException {
256: if (_isFolder) {
257: boolean delete = true;
258: if (!_deleteNotEmpty) {
259: PreparedStatement ps = conn
260: .prepareStatement(COUNT_STR);
261: ps.setString(1, _repositoryId);
262: ps.setString(2, _repoItem.getPath());
263: ResultSet rs = ps.executeQuery();
264: rs.next();
265: delete = rs.getInt(1) == 0;
266: rs.close();
267: ps.close();
268: }
269: if (delete) {
270: PreparedStatement ps;
271: if (_repoItem.equals(RepoItem.ROOT)) {
272: ps = conn.prepareStatement(DELETE_REPO_STR);
273: ps.setString(1, _repositoryId);
274: } else {
275: ps = conn.prepareStatement(DELETE_FOLDER_STR);
276: ps.setString(1, _repositoryId);
277: ps
278: .setString(2, _repoItem.getParent()
279: .getPath());
280: ps.setString(3, _repoItem.getName());
281: ps.setString(4, _repoItem.getPath());
282: ps.setString(5, _repoItem.getPath() + "/%");
283: }
284: int i = ps.executeUpdate();
285: ps.close();
286: } else {
287: throw new RepoException("F062", "Folder not empty",
288: _repoItem);
289: }
290: } else {
291: PreparedStatement ps = conn
292: .prepareStatement(DELETE_FILE_STR);
293: ps.setString(1, _repositoryId);
294: ps.setString(2, _repoItem.getParent().getPath());
295: ps.setString(3, _repoItem.getName());
296: ps.execute();
297: ps.close();
298: }
299: }
300:
301: }
302:
303: public RepoItem getItemInfo(RepoItem item) throws RepoException {
304: if (_logger.isLoggable(Level.FINER)) {
305: _logger.log(Level.FINER, "repository.getItemInfo("
306: + item.getPath() + ")");
307: }
308: if (item.equals(RepoItem.ROOT)) {
309: return RepoItem.ROOT;
310: }
311: SQLExecutor sqlExec = new SQLExecutor(_datasource);
312: GetItemInfoTask giit = new GetItemInfoTask(_repositoryId, item);
313: try {
314: sqlExec.execute(giit);
315: } catch (SQLException ex) {
316: throw new RepoException("F033", "Could not get info", item,
317: ex);
318: }
319: return giit.getRepoItem();
320: }
321:
322: private static class GetItemInfoTask implements SQLTask {
323: private String _repositoryId;
324: private RepoItem _repoItem;
325:
326: public GetItemInfoTask(String repositoryId, RepoItem file) {
327: _repositoryId = repositoryId;
328: _repoItem = file;
329: }
330:
331: public RepoItem getRepoItem() {
332: return _repoItem;
333: }
334:
335: private final static String SELECT_STR = "select repositoryId,directory,name,isDir,creator,created,modified,datasize "
336: + "from filesystem where repositoryId=? and directory=? and name=?";
337:
338: public void run(Connection conn) throws SQLException,
339: RepoException {
340: if (!_repoItem.equals(RepoItem.ROOT)) {
341: PreparedStatement ps;
342: RepoItem parent;
343: parent = _repoItem.getParent();
344: ps = conn.prepareStatement(SELECT_STR);
345: ps.setString(1, _repositoryId);
346: ps.setString(2, _repoItem.getParent().getPath());
347: ps.setString(3, _repoItem.getName());
348: ResultSet rs = ps.executeQuery();
349: if (rs.next()) {
350: _repoItem = new RepoItem(parent, rs.getString(3),
351: rs.getShort(4) == 1, rs.getString(5), rs
352: .getLong(6), rs.getLong(7), rs
353: .getInt(8), true);
354: } else {
355: _repoItem = null;
356: }
357: ps.close();
358: }
359: }
360:
361: }
362:
363: public void addFolder(RepoItem folder) throws RepoException {
364: if (_logger.isLoggable(Level.FINER)) {
365: _logger.log(Level.FINER, "repository.addFolder("
366: + folder.getPath() + ")");
367: }
368: SQLExecutor sqlExec = new SQLExecutor(_datasource);
369: AddFolderTask aft = new AddFolderTask(_repositoryId, folder);
370: try {
371: sqlExec.execute(aft);
372: } catch (SQLException ex) {
373: throw new RepoException("F034", "Could not create folder",
374: folder, ex);
375: }
376: }
377:
378: private static class AddFolderTask implements SQLTask {
379: private String _repositoryId;
380: private RepoItem _folder;
381:
382: public AddFolderTask(String repositoryId, RepoItem folder) {
383: _repositoryId = repositoryId;
384: _folder = folder;
385: }
386:
387: private final static String INSERT_STR = "insert into filesystem "
388: + "(repositoryId,directory,name,isDir,creator,created,modified,datasize) "
389: + "values(?,?,?,1,?,?,?,0)";
390:
391: public void run(Connection conn) throws SQLException {
392: conn.setAutoCommit(false);
393: runWoCommit(conn);
394: conn.commit();
395: }
396:
397: public void runWoCommit(Connection conn) throws SQLException {
398: PreparedStatement ps = conn.prepareStatement(INSERT_STR);
399: ps.setString(1, _repositoryId);
400: ps.setString(2, _folder.getParent().getPath());
401: ps.setString(3, _folder.getName());
402: ps.setString(4, _folder.getCreator());
403: long time = System.currentTimeMillis();
404: ps.setLong(5, time);
405: ps.setLong(6, time);
406: ps.execute();
407: ps.close();
408: }
409: }
410:
411: public RepoItem[] getContent(RepoItem folder) throws RepoException {
412: return getContent(folder, "");
413: }
414:
415: public RepoItem[] getContent(RepoItem folder, String filter)
416: throws RepoException {
417: if (_logger.isLoggable(Level.FINER)) {
418: _logger.log(Level.FINER, "repository.getContent("
419: + folder.getPath() + "," + filter + ")");
420: }
421: SQLExecutor sqlExec = new SQLExecutor(_datasource);
422: GetContentTask gct = new GetContentTask(_repositoryId, folder,
423: filter);
424: try {
425: sqlExec.execute(gct);
426: } catch (SQLException ex) {
427: throw new RepoException("F035", "Could not get contents",
428: folder, ex);
429: }
430: return gct.getContent();
431: }
432:
433: private static class GetContentTask implements SQLTask {
434: private static final String[][] SWAPS = { { "*", "%" },
435: { "?", "_" } };
436:
437: private String _repositoryId;
438: private RepoItem _folder;
439: private String _filter;
440: private RepoItem[] _content;
441:
442: public GetContentTask(String repositoryId, RepoItem folder,
443: String filter) {
444: _repositoryId = repositoryId;
445: _folder = folder;
446: if (filter != null && filter.trim().length() > 0
447: && !filter.trim().equals("*")) {
448: _filter = MaskTranslator.translate(SWAPS, filter);
449: }
450: }
451:
452: public RepoItem[] getContent() {
453: return _content;
454: }
455:
456: private final static String SELECT_WITH_FILTER_STR = "select name,isDir,creator,created,modified,datasize "
457: + "from filesystem where repositoryId=? and directory=? "
458: + "and (isDir=1 or name like ?)";
459:
460: private final static String SELECT_WITHOUT_FILTER_STR = "select name,isDir,creator,created,modified,datasize "
461: + "from filesystem where repositoryId=? and directory=? ";
462:
463: public void run(Connection conn) throws SQLException,
464: RepoException {
465: String select = (_filter != null) ? SELECT_WITH_FILTER_STR
466: : SELECT_WITHOUT_FILTER_STR;
467: PreparedStatement ps = conn.prepareStatement(select);
468: ps.setString(1, _repositoryId);
469: ps.setString(2, _folder.getPath());
470: if ((_filter != null)) {
471: ps.setString(3, _filter);
472: }
473: List l = new ArrayList();
474: ResultSet rs = ps.executeQuery();
475: while (rs.next()) {
476: l
477: .add(new RepoItem(_folder, rs.getString(1), rs
478: .getShort(2) == 1, rs.getString(3), rs
479: .getLong(4), rs.getLong(5), rs
480: .getInt(6), true));
481: }
482: ps.close();
483: _content = new RepoItem[l.size()];
484: l.toArray(_content);
485: }
486:
487: }
488:
489: public void deleteFolder(RepoItem folder, boolean deleteNotEmpty)
490: throws RepoException {
491: if (_logger.isLoggable(Level.FINER)) {
492: _logger.log(Level.FINER, "repository.deleteFolder("
493: + folder.getPath() + "," + deleteNotEmpty + ")");
494: }
495: accessCheck(OP_WRITE, folder);
496: SQLExecutor sqlExec = new SQLExecutor(_datasource);
497: DeleteFileTask dft = new DeleteFileTask(_repositoryId, folder,
498: true, deleteNotEmpty);
499: try {
500: sqlExec.execute(dft);
501: } catch (SQLException ex) {
502: throw new RepoException("F043",
503: "Folder could not be deleted", folder, ex);
504: }
505: }
506:
507: public void copy(RepoItem item, RepoItem folder)
508: throws RepoException {
509: if (_logger.isLoggable(Level.FINER)) {
510: _logger.log(Level.FINER, "repository.copy("
511: + item.getPath() + "," + folder.getPath() + ")");
512: }
513: SQLExecutor sqlExec = new SQLExecutor(_datasource);
514: CopyTask ct = new CopyTask(_repositoryId, item, folder);
515: try {
516: sqlExec.execute(ct);
517: } catch (SQLException ex) {
518: throw new RepoException("F084", "Item could not be copied",
519: item, ex);
520: }
521: }
522:
523: private static class CopyTask implements SQLTask {
524: private String _repositoryId;
525: private RepoItem _source;
526: private RepoItem _target;
527:
528: public CopyTask(String repositoryId, RepoItem source,
529: RepoItem target) {
530: _repositoryId = repositoryId;
531: _source = source;
532: _target = target;
533: }
534:
535: // 1 : target directory
536: // 2,3 : source directory length
537: // 4 : creator
538: // 5,6 : time
539: // 7 : repositoryId
540: // 8 : source directory
541: // 9 : source directory + "/%"
542: private final static String COPY_FOLDER_STR = "insert into filesystem "
543: + "(repositoryId,directory,name,isDir,creator,created,modified,datasize,data) "
544: + ""
545: + " select repositoryId,"
546: + " ? || '/' || substr(directory,?+1,length(directory)-?),"
547: + " name,isDir,?,?,?,datasize,data from filesystem "
548: + " where repositoryId=? and (directory=? or directory like ?) "
549: + "";
550:
551: // 1 : target directory
552: // 2 : creator
553: // 3,4 : time
554: // 5 : resporityId
555: // 6 : source directory
556: // 7 : name
557:
558: private final static String COPY_FILE_STR = "insert into filesystem "
559: + "(repositoryId,directory,name,isDir,creator,created,modified,datasize,data) "
560: + ""
561: + " select repositoryId,"
562: + " ?,"
563: + " name,0,?,?,?,datasize,data from filesystem "
564: + " where repositoryId=? and directory=? and name=?"
565: + "";
566:
567: public void run(Connection conn) throws SQLException,
568: RepoException {
569: conn.setAutoCommit(false);
570: runWoCommit(conn);
571: conn.commit();
572: }
573:
574: public void runWoCommit(Connection conn) throws SQLException,
575: RepoException {
576: GetItemInfoTask giit = new GetItemInfoTask(_repositoryId,
577: _source);
578: giit.run(conn);
579: RepoItem ri = giit.getRepoItem();
580: if (ri == null) {
581: throw new RepoException("F080",
582: "Source item does not exist", _source);
583: }
584: _source = ri;
585: giit = new GetItemInfoTask(_repositoryId, _target);
586: giit.run(conn);
587: ri = giit.getRepoItem();
588: if (ri == null) {
589: throw new RepoException("F081",
590: "Target folder does not exist", _target);
591: }
592: _target = ri;
593: if (!_target.isDirectory()) {
594: throw new RepoException("F082", "Target is not folder",
595: _target);
596: }
597: RepoItem newItem = new RepoItem(_target, _source.getName(),
598: _target.getCreator());
599: giit = new GetItemInfoTask(_repositoryId, newItem);
600: giit.run(conn);
601: if (giit.getRepoItem() != null) {
602: throw new RepoException("F083",
603: "Item already exists in target folder", newItem);
604: }
605: if (_source.isDirectory()) {
606: AddFolderTask aft = new AddFolderTask(_repositoryId,
607: newItem);
608: aft.runWoCommit(conn);
609: PreparedStatement ps = conn
610: .prepareStatement(COPY_FOLDER_STR);
611: ps.setString(1, (_target.equals(RepoItem.ROOT)) ? ""
612: : _target.getPath());
613: ps.setInt(2, _source.getParent().getPath().length()
614: + ((_target.equals(RepoItem.ROOT)) ? 1 : 0));
615: ps.setInt(3, _source.getParent().getPath().length());
616: ps.setString(4, newItem.getCreator());
617: long time = System.currentTimeMillis();
618: ps.setLong(5, time);
619: ps.setLong(6, time);
620: ps.setString(7, _repositoryId);
621: ps.setString(8, _source.getPath());
622: ps.setString(9, _source.getPath() + "/%");
623: ps.execute();
624: ps.close();
625:
626: /*
627: select repositoryId,
628: '/d2.dir' || '/' || substr(directory,1+1,length(directory)-1),
629: name,isDir,'owner',1,1,datasize from test.filesystem
630: where respoitoryId='dummy' and (directory='/d1.dir' or directory like '/d1.dir/%')
631: */
632: } else {
633: PreparedStatement ps = conn
634: .prepareStatement(COPY_FILE_STR);
635: ps.setString(1, newItem.getParent().getPath());
636: ps.setString(2, newItem.getCreator());
637: long time = System.currentTimeMillis();
638: ps.setLong(3, time);
639: ps.setLong(4, time);
640: ps.setString(5, _repositoryId);
641: ps.setString(6, _source.getParent().getPath());
642: ps.setString(7, _source.getName());
643: ps.execute();
644: ps.close();
645: }
646: }
647:
648: }
649:
650: public void move(RepoItem item, RepoItem folder)
651: throws RepoException {
652: if (_logger.isLoggable(Level.FINER)) {
653: _logger.log(Level.FINER, "repository.move("
654: + item.getPath() + "," + folder.getPath() + ")");
655: }
656: if (item.isDirectory()
657: && folder.getPath().startsWith(item.getPath())) {
658: throw new RepoException("F095",
659: "Folder can not be moved to its descendant folder",
660: item, null);
661: }
662: if (!item.isDirectory()) {
663: accessCheck(OP_WRITE, item);
664: }
665: SQLExecutor sqlExec = new SQLExecutor(_datasource);
666: MoveTask mt = new MoveTask(_repositoryId, item, folder);
667: try {
668: sqlExec.execute(mt);
669: } catch (SQLException ex) {
670: throw new RepoException("F094", "Item could not be moved",
671: item, ex);
672: }
673: }
674:
675: //MOVE MAY BE IFY, RENAME IS OK, CHECK ITS LOGIC
676: private static class MoveTask implements SQLTask {
677: private String _repositoryId;
678: private RepoItem _source;
679: private RepoItem _target;
680:
681: public MoveTask(String repositoryId, RepoItem source,
682: RepoItem target) {
683: _repositoryId = repositoryId;
684: _source = source;
685: _target = target;
686: }
687:
688: // 1 : target directory
689: // 2,3 : source directory length
690: // 4 : creator
691: // 5 : time
692: // 6 : repositoryId
693: // 7 : source directory
694: // 8 : source directory + "/%"
695: private final static String MOVE_FOLDER_STR = "update filesystem set directory=? || '/' || substr(directory,?+1,length(directory)-?), "
696: + "creator=?, modified=? "
697: + "where repositoryId=? and (directory=? or directory like ?) ";
698:
699: private final static String MOVE_ITEM_STR = "update filesystem set directory=?,modified=? "
700: + "where repositoryId=? and directory=? and name=? ";
701:
702: public void run(Connection conn) throws SQLException,
703: RepoException {
704: conn.setAutoCommit(false);
705: runWoCommit(conn);
706: conn.commit();
707: }
708:
709: public void runWoCommit(Connection conn) throws SQLException,
710: RepoException {
711: GetItemInfoTask giit = new GetItemInfoTask(_repositoryId,
712: _source);
713: giit.run(conn);
714: RepoItem ri = giit.getRepoItem();
715: if (ri == null) {
716: throw new RepoException("F080",
717: "Source item does not exist", _source);
718: }
719: _source = ri;
720: giit = new GetItemInfoTask(_repositoryId, _target);
721: giit.run(conn);
722: ri = giit.getRepoItem();
723: if (ri == null) {
724: throw new RepoException("F081",
725: "Target folder does not exist", _target);
726: }
727: _target = ri;
728: if (!_target.isDirectory()) {
729: throw new RepoException("F082", "Target is not folder",
730: _target);
731: }
732: RepoItem newItem = new RepoItem(_target, _source.getName(),
733: _target.getCreator());
734: giit = new GetItemInfoTask(_repositoryId, newItem);
735: giit.run(conn);
736: if (giit.getRepoItem() != null) {
737: throw new RepoException("F083",
738: "Item already exists in target folder", newItem);
739: }
740:
741: PreparedStatement ps = conn.prepareStatement(MOVE_ITEM_STR);
742: ps.setString(1, _target.getPath());
743: long time = System.currentTimeMillis();
744: ps.setLong(2, time);
745: ps.setString(3, _repositoryId);
746: ps.setString(4, _source.getParent().getPath());
747: ps.setString(5, _source.getName());
748: ps.execute();
749: ps.close();
750: if (_source.isDirectory()) {
751: ps = conn.prepareStatement(MOVE_FOLDER_STR);
752: ps.setString(1, _target.getPath());
753: ps.setInt(2, _source.getParent().getPath().length());
754: ps.setInt(3, _source.getParent().getPath().length());
755: ps.setString(4, _target.getCreator());
756: ps.setLong(5, time);
757: ps.setString(6, _repositoryId);
758: ps.setString(7, _source.getPath());
759: ps.setString(8, _source.getPath() + "/%");
760: ps.execute();
761: ps.close();
762: }
763: }
764:
765: }
766:
767: public void rename(RepoItem item, String newName)
768: throws RepoException {
769: if (_logger.isLoggable(Level.FINER)) {
770: _logger.log(Level.FINER, "repository.rename("
771: + item.getPath() + "," + newName + ")");
772: }
773: accessCheck(OP_WRITE, item);
774: SQLExecutor sqlExec = new SQLExecutor(_datasource);
775: RenameTask rt = new RenameTask(_repositoryId, item, newName);
776: try {
777: sqlExec.execute(rt);
778: } catch (SQLException ex) {
779: throw new RepoException("F102",
780: "Item could not be renamed to [" + newName + "]",
781: item);
782: }
783: }
784:
785: //RENAME IS OK
786: private static class RenameTask implements SQLTask {
787: private String _repositoryId;
788: private RepoItem _source;
789: private String _newName;
790:
791: public RenameTask(String repositoryId, RepoItem source,
792: String newName) {
793: _repositoryId = repositoryId;
794: _source = source;
795: _newName = newName;
796: }
797:
798: // 1 : target directory
799: // 2,3 : source directory length
800: // 4 : time
801: // 5 : repositoryId
802: // 6 : source directory
803: // 7 : source directory + "/%"
804: private final static String RENAME_FOLDER_STR = "update filesystem set directory= substr(directory,1,?) || ? || substr(directory,?+1,length(directory)-?), "
805: + "modified=? "
806: + "where repositoryId=? and (directory=? or directory like ?) ";
807:
808: private final static String RENAME_ITEM_STR = "update filesystem set name=?,modified=? "
809: + "where repositoryId=? and directory=? and name=? ";
810:
811: public void run(Connection conn) throws SQLException,
812: RepoException {
813: conn.setAutoCommit(false);
814: runWoCommit(conn);
815: conn.commit();
816: }
817:
818: public void runWoCommit(Connection conn) throws SQLException,
819: RepoException {
820: GetItemInfoTask giit = new GetItemInfoTask(_repositoryId,
821: _source);
822: giit.run(conn);
823: RepoItem ri = giit.getRepoItem();
824: if (ri == null) {
825: throw new RepoException("F080",
826: "Source item does not exist", _source);
827: }
828: _source = ri;
829: RepoItem newItem = new RepoItem(_source.getParent(),
830: _newName, _source.getCreator());
831: giit = new GetItemInfoTask(_repositoryId, newItem);
832: giit.run(conn);
833: if (giit.getRepoItem() != null) {
834: throw new RepoException("F083",
835: "Item already exists in target folder", newItem);
836: }
837:
838: PreparedStatement ps = conn
839: .prepareStatement(RENAME_ITEM_STR);
840: ps.setString(1, _newName);
841: long time = System.currentTimeMillis();
842: ps.setLong(2, time);
843: ps.setString(3, _repositoryId);
844: ps.setString(4, _source.getParent().getPath());
845: ps.setString(5, _source.getName());
846: ps.execute();
847: ps.close();
848: if (_source.isDirectory()) {
849: ps = conn.prepareStatement(RENAME_FOLDER_STR);
850: ps.setInt(1, _source.getPath().length()
851: - _source.getName().length());
852: ps.setString(2, newItem.getName());
853: ps.setInt(3, _source.getPath().length());
854: ps.setInt(4, _source.getPath().length());
855: ps.setLong(5, time);
856: ps.setString(6, _repositoryId);
857: ps.setString(7, _source.getPath());
858: ps.setString(8, _source.getPath() + "/%");
859: ps.execute();
860: ps.close();
861: }
862: }
863:
864: }
865:
866: }
|