Skip to content

Instantly share code, notes, and snippets.

@nartamonov
Created November 11, 2011 12:19
Show Gist options
  • Save nartamonov/1357874 to your computer and use it in GitHub Desktop.
Save nartamonov/1357874 to your computer and use it in GitHub Desktop.
Учебное задание по Documentum DFC #1
import com.documentum.com.DfClientX;
import com.documentum.fc.client.*;
import com.documentum.fc.common.DfException;
import com.documentum.fc.common.IDfList;
import com.documentum.fc.common.IDfLoginInfo;
import com.documentum.operations.*;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class DocumentumClient {
static public void main(String[] args) {
if (System.console() == null)
System.exit(-1);
// 1. Получить список доступных репозитариев.
System.out.println("Список доступных репозитариев:");
List<String> docbaseNames = null;
try {
docbaseNames = getAvailableDocbaseNames();
}
catch (DfException e) {
System.out.printf("Не удалось получить список доступных репозитариев (%s).\n", e.getMessage());
System.exit(-1);
}
// 2. Получить доступ к указанному репозитарию из списка.
String selectedDocbaseName = null;
if (docbaseNames.size() == 0) {
System.out.println("\tНИ ОДНОГО РЕПОЗИТАРИЯ");
System.exit(0);
} else while (selectedDocbaseName == null) {
int i = 1;
for (String dn : docbaseNames)
System.out.printf("%d. %s\n", i, dn);
System.out.println();
System.out.print("Укажите номер репозитория для подключения: ");
int number = 0;
try { number = Integer.parseInt(System.console().readLine()); } catch (NumberFormatException e) { }
if (number > 0 && number <= docbaseNames.size())
selectedDocbaseName = docbaseNames.get(number-1);
else
System.out.println("Введен некорректный номер репозитория, попробуйте еще раз.");
}
System.out.print("Введите имя пользователя: ");
String username = System.console().readLine();
System.out.print("Введите пароль: ");
String password = System.console().readLine();
IDfSessionManager sessionManager = null;
try {
DfClientX client = new DfClientX();
sessionManager = client.getLocalClient().newSessionManager();
IDfLoginInfo loginInfo = client.getLoginInfo();
loginInfo.setUser(username);
loginInfo.setPassword(password);
sessionManager.setIdentity(selectedDocbaseName, loginInfo);
}
catch (DfException e) {
System.out.printf("В процессе инициализации клиентского кода возникла фатальная ошибка: %s\n",
e.getMessage());
System.exit(-1);
}
try {
withSession(sessionManager, selectedDocbaseName, new Function1<IDfSession, Void, DfException>() {
public Void apply(IDfSession session) throws DfException {
doRealWork(session);
return null;
}
});
}
catch (DfException e) {
System.out.printf("В процессе работы возникла фатальная ошибка: %s\n", e.getMessage());
e.printStackTrace();
System.exit(-1);
}
}
static public void doRealWork(IDfSession session) throws DfException {
// 3. Получить список кабинетов.
System.out.println("Список кабинетов:");
for (IDfFolder cabinet : listCabinets(session))
System.out.println(cabinet.getObjectName());
System.out.println();
// 4. Получить список содержимого домашнего кабинета пользователя.
System.out.println("Содержимое домашнего кабинета пользователя:");
for (IDfTypedObject obj : getHomeCabinetContents(session))
System.out.println(obj.getString("object_name"));
System.out.println();
// 5. Создать новую папку в домашнем кабинете.
System.out.print("Создадим новую папку в домашнем кабинете. Введите название папки: ");
String folderName = System.console().readLine();
IDfFolder newFolder = createFolderInHomeCabinet(session, folderName);
System.out.println("\tOK\n");
// 6. Создать новый документ в этой папке.
// 7. Импортировать контента для созданного документа.
System.out.print("Создадим новый документ в этой папке. Введите название док-та: ");
String docName = System.console().readLine();
ByteArrayOutputStream content = new ByteArrayOutputStream();
(new PrintStream(content)).print("Содержимое тестового документа.");
IDfDocument newDoc = createNewDocument(session,
docName,
docName,
content,
"crtext"); // content-type: Text Document (windows)
System.out.println("\tOK\n");
// 8. Создать новую папку в домашнем кабинете.
System.out.print("Создадим новую папку в домашнем кабинете. Введите название папки: ");
String folderName2 = System.console().readLine();
IDfFolder newFolder2 = createFolderInHomeCabinet(session, folderName2);
System.out.println("\tOK\n");
// 9. Слинковать документ в новую папку.
System.out.print("Слинкуем документ в новую папку: ");
linkDocToFolder(newDoc, newFolder2);
System.out.println("OK\n");
// 10. Получить список локаций созданного документа.
System.out.println("Список локаций созданного документа:");
for (IDfFolder loc : getObjLocations(newDoc))
System.out.println(loc.getObjectName());
System.out.println();
// 11. Выписать документ.
System.out.println("Выписываем документ в домашнюю директорию пользователя.");
List<IDfOperationError> errs = checkOutTo(newDoc, System.getProperty("user.home"));
if (errs.isEmpty())
System.out.println("\tOK");
else
for (IDfOperationError err : errs)
System.out.printf("\tОшибка: %s\n", err.getMessage());
System.out.println();
// 12. Отменить выписку.
System.out.println("Отменяем выписку.");
errs = cancelCheckOut(newDoc, false);
if (errs.isEmpty())
System.out.println("\tOK");
else
for (IDfOperationError err : errs)
System.out.printf("\tОшибка: %s\n", err.getMessage());
System.out.println();
// 13. Выписать документ.
System.out.println("Выписываем документ в домашнюю директорию пользователя.");
errs = checkOutTo(newDoc, System.getProperty("user.home"));
if (errs.isEmpty())
System.out.println("\tOK");
else
for (IDfOperationError err : errs)
System.out.printf("\tОшибка: %s\n", err.getMessage());
System.out.println();
// 14. Вернуть документ с созданием мажорной версии.
System.out.print("Производим следующую мажорную версию док-та. Версия: ");
IDfSysObject nextVer = deriveNewMajorVersionOf(newDoc);
System.out.println(nextVer.getVersionPolicy().getVersionSummary(" "));
System.out.println();
// 15. Получить список версий созданного документа.
System.out.println("Список версий созданного документа:");
for (String ver : getAvailableVersions(newDoc))
System.out.println("\t" + ver);
System.out.println();
// 16. Удалить все объекты, созданные в процессе выполнения задания.
// System.out.println("Удаляем все ранее созданные объекты.");
// errs = deleteObjects(newDoc, newFolder, newFolder2);
// if (errs.isEmpty())
// System.out.println("\tOK");
// else
// for (IDfOperationError err : errs)
// System.out.printf("\tОшибка: %s\n", err.getMessage());
}
/**
* 1. Получить список доступных репозитариев.
*/
static public List<String> getAvailableDocbaseNames() throws DfException {
List<String> docbaseList = new ArrayList<String>();
IDfDocbaseMap docbaseMap = DfClient.getInstance().getDocbaseMap();
int docbaseCount = docbaseMap.getDocbaseCount();
for (int idx = 0; idx < docbaseCount; ++idx) {
docbaseList.add(docbaseMap.getDocbaseName(idx));
}
return docbaseList;
}
/**
* 2. Получить доступ к указанному репозитарию из списка.
*/
static public <T,E extends Throwable> T withSession(IDfSessionManager sessionManager, String docbase,
Function1<IDfSession, T, E> f) throws E, DfIdentityException,
DfAuthenticationException,
DfPrincipalException,
DfServiceException {
assert sessionManager != null;
IDfSession session = null;
try {
session = sessionManager.getSession(docbase);
return f.apply(session);
}
finally {
if (session != null)
sessionManager.release(session);
}
}
/**
* 3. Получить список кабинетов.
*/
static public List<IDfFolder> listCabinets(IDfSession session) throws DfException {
IDfEnumeration en = session.getObjectsByQuery(
"SELECT r_object_id, object_name, i_vstamp, r_object_type, r_aspect_name, i_is_replica, i_is_reference " +
"FROM dm_cabinet", "dm_cabinet");
return readDfcEnumeration(en, IDfFolder.class);
}
/**
* 4. Получить список содержимого домашнего кабинета пользователя.
*/
static public List<IDfSysObject> getHomeCabinetContents(IDfSession session) throws DfException {
IDfFolder homeCabinet = session.getFolderByPath(getCurrentUser(session).getDefaultFolder());
return readDfcEnumeration(
session.getObjectsByQuery(
String.format("SELECT r_object_id, object_name, i_vstamp, r_object_type, r_aspect_name, i_is_replica, i_is_reference " +
"FROM dm_sysobject WHERE ANY i_folder_id = '%s'",
homeCabinet.getObjectId().getId()), "dm_sysobject"),
IDfSysObject.class);
}
static public IDfUser getCurrentUser(IDfSession session) throws DfException {
return session.getUser(session.getLoginUserName());
}
static public IDfFolder getHomeCabinet(IDfSession session) throws DfException {
return session.getFolderByPath(getCurrentUser(session).getDefaultFolder());
}
/**
* 5. Создать новую папку в домашнем кабинете.
*/
static public IDfFolder createFolderInHomeCabinet(IDfSession session, String folderName) throws DfException {
IDfFolder homeCabinet = getHomeCabinet(session);
IDfFolder newFolder = (IDfFolder)session.newObject("dm_folder");
newFolder.setObjectName(folderName);
newFolder.link(homeCabinet.getObjectId().getId());
newFolder.save();
return newFolder;
}
/**
* 6. Создать новый документ в этой папке.
* 7. Импортировать контента для созданного документа.
*/
static public IDfDocument createNewDocument(IDfSession session, String docName, String docTitle,
ByteArrayOutputStream content,
String contentType) throws DfException {
IDfDocument newDocument = (IDfDocument)session.newObject("dm_document");
newDocument.setObjectName(docName);
newDocument.setTitle(docTitle);
newDocument.setContentType(contentType);
newDocument.setContent(content);
newDocument.save();
return newDocument;
}
/**
* 9. Слинковать документ в новую папку.
*/
static public void linkDocToFolder(IDfDocument doc, IDfFolder folder) throws DfException {
doc.link(folder.getObjectId().getId());
doc.save();
}
/**
* 10. Получить список локаций созданного документа.
*/
static public List<IDfFolder> getObjLocations(IDfSysObject obj) throws DfException {
// Могли бы использовать IDfSysObject#getLocations() или IDfSysObject#getFolderID(),
// получилось бы более красиво - меньше деталей реализации, затронутых в ручном DQL-запросе.
// Но тогда решение было бы очень неэффективным - большое количество вызовов DFC методов,
// которые приведут к увеличению сетевого трафика и соответствующих задержек.
// В данном случае вся работа по поиску связанных папок перекладывается на сервер, мы
// получаем только результат.
return readDfcEnumeration(obj.getSession().getObjectsByQuery(
String.format("SELECT r_object_id, i_vstamp, r_object_type, r_aspect_name, i_is_replica, i_is_reference FROM dm_folder " +
"WHERE r_object_id IN (SELECT i_folder_id FROM dm_document WHERE r_object_id = '%s')",
obj.getObjectId().getId()), "dm_folder"),
IDfFolder.class);
}
/**
* 11. Выписать документ.
*/
static public List<IDfOperationError> checkOutTo(IDfSysObject doc, final String localPath) throws DfException {
return genericPerformOperation(new Function1<DfClientX, IDfOperation, DfException>() {
public IDfOperation apply(DfClientX client) throws DfException {
IDfCheckoutOperation op = client.getCheckoutOperation();
op.setDestinationDirectory(localPath);
return op;
}
}, doc);
}
/**
* 12. Отменить выписку.
*/
static public List<IDfOperationError> cancelCheckOut(IDfSysObject obj, final boolean keepLocalFile) throws DfException {
return genericPerformOperation(new Function1<DfClientX, IDfOperation, DfException>() {
public IDfOperation apply(DfClientX client) throws DfException {
IDfCancelCheckoutOperation op = client.getCancelCheckoutOperation();
op.setKeepLocalFile(keepLocalFile);
return op;
}
}, obj);
}
/**
* Обобщенный метод выполнения операции DFC над совокупностью объектов <pre>objs</pre>.
* Функция <pre>setupOp</pre> ответственна за создание и корректную инициализацию требуемой
* операции.
*
* @return список ошибок, возникших при выполнении операции
* @throws DfException
*/
static public List<IDfOperationError> genericPerformOperation(Function1<DfClientX, IDfOperation, DfException> setupOp,
Object... objs) throws DfException {
List<IDfOperationError> errors = new ArrayList<IDfOperationError>();
IDfOperation op = setupOp.apply(new DfClientX());
for (Object obj : objs)
if (op.add(obj) == null)
throw new DfUserException("IDfOperation.add() returned null.", null, null);
if (!op.execute()) {
IDfList errs = op.getErrors();
for (int idx = 0; idx < errs.getCount(); ++idx)
errors.add((IDfOperationError)errs.get(idx));
}
return errors;
}
/**
* 14. Вернуть документ с созданием мажорной версии.
*
* @return new object or <pre>null</pre> if object was not created
*/
static IDfSysObject deriveNewMajorVersionOf(IDfSysObject obj) throws DfException {
IDfCheckinOperation op = (new DfClientX()).getCheckinOperation();
op.setCheckinVersion(IDfVersionPolicy.DF_NEXT_MAJOR);
op.setVersionLabels("CURRENT");
if (!obj.isCheckedOut())
obj.checkout();
IDfCheckinNode node = (IDfCheckinNode)op.add(obj);
if (node == null || !op.execute())
return null;
else
return node.getNewObject();
}
/**
* 15. Получить список версий созданного документа.
*/
static public List<String> getAvailableVersions(IDfSysObject obj) throws DfException {
List<IDfTypedObject> objs = readDfcCollection(obj.getVersions(null), IDfTypedObject.class);
List<String> versions = new ArrayList<String>();
for (IDfTypedObject o : objs) versions.add(o.getString("r_object_id") + ": " + o.getString("r_version_label"));
return versions;
}
/**
* 16. Удалить все объекты, созданные в процессе выполнения задания.
*/
static public List<IDfOperationError> deleteObjects(IDfSysObject... objs) throws DfException {
return genericPerformOperation(new Function1<DfClientX, IDfOperation, DfException>() {
public IDfOperation apply(DfClientX client) throws DfException {
IDfDeleteOperation op = client.getDeleteOperation();
op.enableDeepDeleteFolderChildren(true);
op.setDeepFolders(true);
op.setVersionDeletionPolicy(2); // delete ALL versions
return op;
}
}, objs);
}
static public <T extends IDfTypedObject> List<T> readDfcCollection(IDfCollection coll, Class<T> castTo) throws DfException {
List<T> list = new ArrayList<T>();
while (coll.next())
list.add(castTo.cast(coll.getTypedObject()));
coll.close();
return list;
}
static public <T> List<T> readDfcEnumeration(IDfEnumeration enumeration, Class<T> castTo) {
List<T> list = new ArrayList<T>();
while (enumeration.hasMoreElements())
list.add(castTo.cast(enumeration.nextElement()));
return list;
}
public interface Function1<U,V,E extends Throwable> {
public V apply(U arg) throws E;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment