问题
Given the fact i have a versionable node with a versionable subnode. I checkin the first node with 1 subnode for version 1.0. Now i add a new subnode on parentnode (1.1). If i restore parentnode on version 1.0 i can see theres only first checkedin subnode available. When i now wanna restore parent back to version 1.1 and try to get VersionHistory for second subnode ill receive a pathNotfoundException while querying. I did ...restore(absPath, restoreToVersion, false);
public static final String LESSON = "lesson_";
public static final String FILECARD = "filecard_";
public static final String USER = "user_";
public static final String DEL = "/";
public static final SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy HH:mm");
/**
*
* @param entityList
* @param userID
* @throws IOException
*
* Neue Lektion wurde im Desktop Client angelegt ode vorhandene geändert.
* Abhängig davon wird hier ein neuer Lektionsknoten angelegt oder der vorhandene geändert.
* Jedem Knoten wird das serialisierte Lessonentity als property angehängt.
*/
public void insertLesson(List<LessonEntity> entityList, String userID) throws IOException {
Session session = JRRepository.getInstance().getSession();
Workspace ws = session.getWorkspace();
try {
Node userNode = handleLessonParentNodes(entityList.get(0), userID, session);
for (LessonEntity lessonEntity : entityList) {
// check wether lesson node already exists
if (userNode.hasNode(LESSON + lessonEntity.getID())) {
Node lessonNode = userNode.getNode(LESSON + lessonEntity.getID());
ws.getVersionManager().checkout(lessonNode.getPath());
lessonNode.setProperty("data", JRUtils.serializObject(lessonEntity));
session.save();
ws.getVersionManager().checkin(lessonNode.getPath());
} else {
// if not we add a new one
insertNewLessonNode(userID, lessonEntity, session);
}
}
} catch (RepositoryException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
session.logout();
}
}
/**
*
* @param fileCardEntityList
* @param userID
* @throws IOException
*
* Neue Filecard wurde im Desktop Client angelegt oder Vorhandene geändert.
* Abhängig davon wird hier das gleiche gemacht.
* Jedem Knoten wird das serialisierte Filecardentity als property angehängt.
*/
public void insertFileCards(List<FileCardEntity> fileCardEntityList, String userID) {
Session session = JRRepository.getInstance().getSession();
Workspace ws = session.getWorkspace();
try {
Node lessonNode = null;
boolean createNewLessonVersion = true;
for (FileCardEntity fileCardEntity : fileCardEntityList) {
lessonNode = handleFileCardParentNodes(fileCardEntity, userID, session);
nodeCheckout(lessonNode, session);
// check wether fileCardNode already exists
if (lessonNode.hasNode(FILECARD + fileCardEntity.getID())) {
Node fileCardNode = lessonNode.getNode(FILECARD + fileCardEntity.getID());
nodeCheckout(fileCardNode, session);
fileCardNode.setProperty("data", JRUtils.serializObject(fileCardEntity));
fileCardNode.setProperty("versionDate", Calendar.getInstance().getTimeInMillis());
session.save();
nodeCheckin(fileCardNode, session);
} else {
// if not we add a new one
if(createNewLessonVersion){
nodeCheckin(lessonNode, session);
nodeCheckout(lessonNode, session);
createNewLessonVersion = false;
}
insertNewFileCardNode(lessonNode, fileCardEntity, userID, session);
}
}
} catch (RepositoryException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
session.logout();
}
}
public Node insertNewUserNode(String userID, Session session) throws ItemExistsException, PathNotFoundException, VersionException, ConstraintViolationException, LockException, RepositoryException {
Node userNode = session.getRootNode().addNode(USER + userID);
session.save();
return userNode;
}
public Node insertNewLessonNode(String userID, LessonEntity lessonEntity, Session session) throws PathNotFoundException, RepositoryException, IOException {
// that adds a usernode if not there already
Node userNode = handleLessonParentNodes(lessonEntity, userID, session);
Node lessonNode = userNode.addNode(LESSON + lessonEntity.getID(), "nt:unstructured");
lessonNode.addMixin("mix:versionable");
lessonNode.setProperty("id", lessonEntity.getID());
lessonNode.setProperty("data", JRUtils.serializObject(lessonEntity));
session.save();
session.getWorkspace().getVersionManager().checkin(lessonNode.getPath());
return lessonNode;
}
public Node insertNewFileCardNode(Node lessonNode, FileCardEntity fileCardEntity, String userID, Session session) throws UnsupportedRepositoryOperationException, RepositoryException, IOException {
Node fileCardNode = null;
fileCardNode = lessonNode.addNode(FILECARD + fileCardEntity.getID(), "nt:unstructured");
fileCardNode.addMixin("mix:versionable");
fileCardNode.setProperty("data", JRUtils.serializObject(fileCardEntity));
fileCardNode.setProperty("versionDate", Calendar.getInstance().getTimeInMillis());
session.save();
session.getWorkspace().getVersionManager().checkin(lessonNode.getPath() + DEL + FILECARD + fileCardEntity.getID());
return fileCardNode;
}
/**
*
* @param lessonId
* @param fileCardId
* @param userID
* @param versionName
* @throws PathNotFoundException
* @throws RepositoryException
* @throws IOException
* @throws ClassNotFoundException
*
* Stellt eine Version dieser Filecard wieder her und lädt sie auf den Server.
*/
public void restoreFileCard(String lessonId, String fileCardId, String userID, String versionName) throws PathNotFoundException, RepositoryException, IOException, ClassNotFoundException {
Session session = JRRepository.getInstance().getSession();
String userNodePath = session.getRootNode().getNode(USER + userID).getPath();
String absPath = userNodePath + DEL + LESSON + lessonId + DEL + FILECARD + fileCardId;
VersionHistory versionHistory = getVersionHistory(session, absPath);
VersionIterator iterator = versionHistory.getAllVersions();
FileCardEntity cardEntity = null;
while (iterator.hasNext()) {
Version version = (Version) iterator.next();
if (version.getName().equals(versionName)) {
Node node = version.getFrozenNode();
Value value = node.getProperty("data").getValue();
Object ob = JRUtils.deSerializeObject(value.getBinary());
cardEntity = (FileCardEntity) ob;
}
}
session.getWorkspace().getVersionManager().restore(absPath, versionName, false);
List<FileCardEntity> updateList = new ArrayList<FileCardEntity>();
cardEntity.setLastModified(new Date());
updateList.add(cardEntity);
fileCardDao.updateFileCardList(userID, updateList);
session.logout();
}
/**
*
* @param lessonId
* @param userID
* @param restoreToVersion
* @throws SQLException
* @throws VersionException
* @throws ItemExistsException
* @throws UnsupportedRepositoryOperationException
* @throws LockException
* @throws InvalidItemStateException
* @throws RepositoryException
*
* Stellt eine Version dieser Lektion inklusive der derzeit aktiven Filekarten wieder her und lädt sie auf den Server.
*/
public void restoreLesson(String lessonId, String userID, String restoreToVersion) throws SQLException, VersionException, ItemExistsException, UnsupportedRepositoryOperationException, LockException, InvalidItemStateException, RepositoryException {
Session session = JRRepository.getInstance().getSession();
String userNodePath = session.getRootNode().getNode(USER + userID).getPath();
String absPath = userNodePath + DEL + LESSON + lessonId;
String baseVersion = getBaseVersion(session, absPath).getName();
VersionHistory versionHistory = getVersionHistory(session, absPath);
Version version = versionHistory.getVersion(restoreToVersion);
LessonEntity lessonEntity = null;
List<FileCardEntity> list = new ArrayList<FileCardEntity>();
Node frozenNode = version.getFrozenNode();
Value value = frozenNode.getProperty("data").getValue();
Object ob = JRUtils.deSerializeObject(value.getBinary());
lessonEntity = (LessonEntity) ob;
list = handleFileCards(session, restoreToVersion, absPath, baseVersion);
List<LessonEntity> updateList = new ArrayList<LessonEntity>();
lessonEntity.setLastModified(new Date());
lessonEntity.setStatus(StatusType.ACTIVE);
updateList.add(lessonEntity);
lessonDao.updateLessons(updateList, userID);
if (list != null && list.size() > 0) {
for (FileCardEntity cardEntity : list) {
cardEntity.setLastModified(new Date());
}
fileCardDao.updateFileCardList(userID, list);
}
session.getWorkspace().getVersionManager().restore(absPath, restoreToVersion, false);
session.logout();
}
/**
*
* @param session
* @param requestedVersion
* @param absPath
* @param currentVersion
* @return List<FileCardEntity>
* @throws ValueFormatException
* @throws PathNotFoundException
* @throws RepositoryException
*
* Hier werden die jeweiligen Filecards identifiziert, die zwischen der jetzigen Version und der gewünschten Version liegen.
* Die jeweiliegen Filecards werden entsprechend ihres Verhaltens mit <StatusType> markiert und als java objekte zurückgegeben.
*/
private List<FileCardEntity> handleFileCards(Session session, String requestedVersion, String absPath, String currentVersion) throws ValueFormatException, PathNotFoundException, RepositoryException {
Map<String, FileCardEntity> requestedFilecardMap = new HashMap<String, FileCardEntity>();
Map<String, FileCardEntity> currentFilecardMap = new HashMap<String, FileCardEntity>();
List<FileCardEntity> requestedList = new ArrayList<FileCardEntity>();
// currentVersion
Version currVersion = getVersionHistory(session, absPath).getVersion(currentVersion);
Node lektion = currVersion.getFrozenNode();
for (NodeIterator iterator2 = lektion.getNodes(); iterator2.hasNext();) {
Node fileCardEntityNode = (Node) iterator2.next();
Version baseVersion = getBaseVersion(session, absPath + DEL + fileCardEntityNode.getName());
Node filecardFrozenNode = baseVersion.getFrozenNode();
if (filecardFrozenNode.hasProperty("data")) {
Value fileCardProperty = filecardFrozenNode.getProperty("data").getValue();
Object obj = JRUtils.deSerializeObject(fileCardProperty.getBinary());
FileCardEntity cardEntity = (FileCardEntity) obj;
currentFilecardMap.put(fileCardEntityNode.getName(), cardEntity);
}
}
// requested Version
Node reqFrozenNode = null;
Version reqVersion = getVersionHistory(session, absPath).getVersion(requestedVersion);
reqFrozenNode = reqVersion.getFrozenNode();
for (NodeIterator iterator3 = reqFrozenNode.getNodes(); iterator3.hasNext();) {
Node fcNode = (Node) iterator3.next();
Version fileCardVersion = determineFileCardVersion(session, reqVersion, absPath, fcNode);
fcNode = fileCardVersion.getFrozenNode();
if (fcNode.hasProperty("data")) {
Value value = fcNode.getProperty("data").getValue();
FileCardEntity cardEntity = (FileCardEntity) JRUtils.deSerializeObject(value.getBinary());
String name = FILECARD + cardEntity.getID();
requestedFilecardMap.put(name, cardEntity);
}
}
for (Map.Entry<String, FileCardEntity> entry : currentFilecardMap.entrySet()) {
FileCardEntity cardEntity = entry.getValue();
// angeforderte Version hat die selbe Filekarte
if (requestedFilecardMap.containsKey(entry.getKey())) {
addToReturnList(requestedList, StatusType.ACTIVE, cardEntity);
requestedFilecardMap.remove(entry.getKey());
// angeforderte Version hat nicht diese Filekarte
} else if (!requestedFilecardMap.containsKey(entry.getKey())) {
addToReturnList(requestedList, StatusType.REMOVED, cardEntity);
}
}
for (Map.Entry<String, FileCardEntity> entry : requestedFilecardMap.entrySet()) {
FileCardEntity cardEntity = entry.getValue();
// angeforderte Version hat Filekarte die in der currentVersion
// nicht drin war
if (!currentFilecardMap.containsKey(entry.getKey())) {
addToReturnList(requestedList, StatusType.ACTIVE, cardEntity);
}
}
return requestedList;
}
/**
*
* @param session
* @param lektionsVersion
* @param absPath
* @param filecardFrozenNode
* @return Version
* @throws UnsupportedRepositoryOperationException
* @throws RepositoryException
*
* Hier wird die jewilige Filecardversion identifiziert die zum Zeitpunkt der Lektionsversion aktiv war.
*/
private Version determineFileCardVersion(Session session, Version lektionsVersion, String absPath, Node filecardFrozenNode) throws UnsupportedRepositoryOperationException, RepositoryException {
Calendar nextLessonStart = lektionsVersion.getLinearPredecessor().getCreated();
Version preVersion = null;
VersionHistory filecardHistory = null;
try{
filecardHistory = getVersionHistory(session, absPath + DEL + filecardFrozenNode.getName());
}catch(PathNotFoundException pne){
filecardHistory = getVersionHistory(session, session.getRootNode().getPath() + filecardFrozenNode.getName());
}
for (VersionIterator iterator = filecardHistory.getAllVersions(); iterator.hasNext();) {
Version filecardVersion = (Version) iterator.next();
if (!filecardVersion.getName().startsWith("jcr:root")) {
Calendar fc = filecardVersion.getCreated();
if (fc.before(nextLessonStart)) {
preVersion = filecardVersion;
} else {
if (null == preVersion) {
return filecardVersion;
}
}
}
}
return preVersion;
}
public Node handleFileCardParentNodes(FileCardEntity entity, String userID, Session session) throws PathNotFoundException, RepositoryException, IOException {
if (!isLessonNodeAvailable(entity, userID, session)) {
LessonEntity lessonEntity = lessonDao.get(entity.getLesson().getID());
return insertNewLessonNode(userID, lessonEntity, session);
} else {
return session.getNode(DEL + USER + userID + DEL + LESSON + entity.getLesson().getID());
}
}
public Node handleLessonParentNodes(LessonEntity entity, String userID, Session session) throws PathNotFoundException, RepositoryException, IOException {
if (!isUserNodeAvailable(userID, session)) {
return insertNewUserNode(userID, session);
} else {
return session.getNode(DEL + USER + userID);
}
}
private void nodeCheckout(Node node, Session session) throws VersionException, UnsupportedRepositoryOperationException, InvalidItemStateException, LockException, RepositoryException {
session.getWorkspace().getVersionManager().checkout(node.getPath());
}
private void nodeCheckin(Node node, Session session) throws VersionException, UnsupportedRepositoryOperationException, InvalidItemStateException, LockException, RepositoryException {
session.getWorkspace().getVersionManager().checkin(node.getPath());
}
public VersionHistory getVersionHistory(Session session, String absPath) throws UnsupportedRepositoryOperationException, RepositoryException {
return session.getWorkspace().getVersionManager().getVersionHistory(absPath);
}
private Version getBaseVersion(Session session, String absPath) throws UnsupportedRepositoryOperationException, RepositoryException {
return session.getWorkspace().getVersionManager().getBaseVersion(absPath);
}
private boolean isUserNodeAvailable(String userID, Session session) throws PathNotFoundException, RepositoryException {
return session.getRootNode().hasNode(USER + userID);
}
private void addToReturnList(List<FileCardEntity> list, StatusType status, FileCardEntity entity) {
entity.setStatus(status);
list.add(entity);
}
private boolean isLessonNodeAvailable(FileCardEntity entity, String userID, Session session) throws PathNotFoundException, RepositoryException, IOException {
LessonEntity lessonEntity = entity.getLesson();
if (null == lessonEntity)
return false;
Node userNode = null;
if (!isUserNodeAvailable(userID, session)) {
userNode = insertNewUserNode(userID, session);
}
userNode = session.getNode(DEL + USER + userID);
return userNode.hasNode(LESSON + lessonEntity.getID());
}
Is ist possible that versionhistory is deleted for that subnode by restoring parentnode to version subnode doesent exists ?
Any help would be appreciated ....thanks in advance !!
Additional code comment
First i have to be able to version lessons and filecards undependend. This is the reason why i made both versionable. In client someone creates a lesson and a filecard, then synchs to server. First insertLesson is called and version 1.0 is created. Then insertFilecard is called and generates lessonversion 1.1, then filecardversion 1.0. Now client creates new Filecard and synchs, so second filecard is created and lesson version 1.2. Now i restore back to lesson version 1.1 with restoreLesson method. Inside that i call a handleFilecard method that checks the filecard differences between current and requested lesson versions. No problem so far version 1.1 is restored and we remember, at that time we only had one filecard. Now i try to switch back to lesson version 1.2. In the handleFilecards method is a determineFileCardVersion called that should return the version of a filecard at the time a given lesson version was active . Inside is a try catch approach to test additional possibilities to get the versionhistory of that filecard we added for lesson version 1.2. But no success, the versionhistory for that filecard seems to be gone after restore to lesson version 1.1.... hope that isnt too much and sry for my bad english :)
来源:https://stackoverflow.com/questions/29945095/versionhistory-of-node-disappered-after-restore-parentnode-to-lower-version-jack