Skip to content

Commit

Permalink
ora-663 save / saveAs problems solved
Browse files Browse the repository at this point in the history
  • Loading branch information
rbudde committed Sep 23, 2015
1 parent 5821362 commit ddc5765
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 86 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -164,17 +164,16 @@ private Program getProgramWithAccessRight(String programName, int ownerId) {
}

/**
* update a given program owned by a given user. Overwrites an existing program if mayExist == true.
* insert or update a given program owned by a given user. Overwrites an existing program if mayExist == true.
*
* @param programName the name of the program
* @param userId the owner of the program
* @param robotId
* @param programText the new program text
* @param programTimestamp Program timestamp
* @param mayExist true, if an existing program may be changed; false if a program may be stored only, if it does not exist in the database
* @param robotId the id of the robot the program was written for
* @param programText the program text
* @param programTimestamp timestamp of the last change of the program (if it already existed); <code>null</code> if a new program is saved
* @param isOwner true, if the owner updates a program; false if a user with access right WRITE updates a program
*/
public Program updateProgram(String programName, int userId, int robotId, String programText, Timestamp programTimestamp, boolean isOwner) {
public Program persistProgramText(String programName, int userId, int robotId, String programText, Timestamp programTimestamp, boolean isOwner) {
if ( !Util.isValidJavaIdentifier(programName) ) {
setError(Key.PROGRAM_ERROR_ID_INVALID, programName);
return null;
Expand All @@ -185,8 +184,13 @@ public Program updateProgram(String programName, int userId, int robotId, String
ProgramDao programDao = new ProgramDao(this.dbSession);
User user = userDao.get(userId);
Robot robot = robotDao.get(robotId);
Pair<Key, Program> result = programDao.persistProgramText(programName, user, robot, programText, programTimestamp, isOwner);
// a bit strange, but necessary to distinguish between success and failure
Pair<Key, Program> result;
if ( isOwner ) {
result = programDao.persistOwnProgram(programName, user, robot, programText, programTimestamp);
} else {
result = programDao.persistSharedProgramText(programName, user, robot, programText, programTimestamp);
}
// a bit strange, but necessary as Java has no N-tuple
if ( result.getFirst() == Key.PROGRAM_SAVE_SUCCESS ) {
setSuccess(Key.PROGRAM_SAVE_SUCCESS);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,58 +37,72 @@ public ProgramDao(DbSession session) {
}

/**
* make a program object and persist it (if the program, identified by owner&name&robot, does not exist) or update it (if the program exists)
* persist a program object that is owned by the caller
*
* @param name the name of the program, never null
* @param user the user who owns the program, never null
* @param robotId
* @param programText the program text, maybe null
* @param timestamp timestamp of the program, never null
* @param isOwner true, if the owner updates a program; false if a user with access right WRITE updates a program
* @return true if the program could be persisted successfully
* @param robotId the robot the program was written for
* @param programText the program text
* @param programTimestamp timestamp of the last change of the program (if it already existed); <code>null</code> if a new program is saved
* @return a pair of (message-key, program). If the program is persisted successfully, the program is NOT null.
*/
public Pair<Key, Program> persistProgramText(String name, User user, Robot robot, String programText, Timestamp timestamp, boolean isOwner) {
public Pair<Key, Program> persistOwnProgram(String name, User user, Robot robot, String programText, Timestamp timestamp) {
Assert.notNull(name);
Assert.notNull(user);
Assert.notNull(robot);
Assert.notNull(timestamp);

if ( isOwner ) {
Program program = load(name, user, robot);
if ( program == null ) {
if ( timestamp.equals(new Timestamp(0)) ) {
// the program doesn't exist, thus the expected timestamp must not be set
program = new Program(name, user, robot);
program.setProgramText(programText);
this.session.save(program);
return Pair.of(Key.PROGRAM_SAVE_SUCCESS, program); // the only legal key if success
} else {
// otherwise ...
ProgramDao.LOG.error("update was requested, but no program with matching timestamp was found");
return Pair.of(Key.PROGRAM_SAVE_ERROR_NO_PROGRAM_TO_UPDATE_FOUND, null);
}
} else if ( !timestamp.equals(program.getLastChanged()) ) {
ProgramDao.LOG.error("update was requested, timestamps don't match. Has another user updated the program in the meantime?");
return Pair.of(Key.PROGRAM_SAVE_ERROR_OPTIMISTIC_TIMESTAMP_LOCKING, null);
} else {
Program program = load(name, user, robot);
if ( program == null ) {
if ( timestamp == null ) {
// save as && the program doesn't exist.
program = new Program(name, user, robot);
program.setProgramText(programText);
this.session.save(program);
return Pair.of(Key.PROGRAM_SAVE_SUCCESS, program); // the only legal key if success
} else {
return Pair.of(Key.PROGRAM_SAVE_ERROR_PROGRAM_TO_UPDATE_NOT_FOUND, null);
}
} else {
Program program = loadSharedForUpdate(name, user, robot);
if ( program == null ) {
ProgramDao.LOG.error("update was requested, but no shared program was found");
return Pair.of(Key.PROGRAM_SAVE_ERROR_NO_WRITE_PERMISSION, null);
} else if ( !timestamp.equals(program.getLastChanged()) ) {
ProgramDao.LOG.error("update was requested, timestamps don't match. Has another user updated the program in the meantime?");
return Pair.of(Key.PROGRAM_SAVE_ERROR_OPTIMISTIC_TIMESTAMP_LOCKING, null);
} else {
if ( timestamp == null ) {
// save as && the program exists.
return Pair.of(Key.PROGRAM_SAVE_AS_ERROR_PROGRAM_EXISTS, null);
} else if ( timestamp.equals(program.getLastChanged()) ) {
program.setProgramText(programText);
return Pair.of(Key.PROGRAM_SAVE_SUCCESS, program); // the only legal key if success
} else {
ProgramDao.LOG.error("update was requested, timestamps don't match. Has another user updated the program in the meantime?");
return Pair.of(Key.PROGRAM_SAVE_ERROR_OPTIMISTIC_TIMESTAMP_LOCKING, null);
}
}
}

/**
* persist a program object that the owner shared with the caller
*
* @param name the name of the program, never null
* @param user the user who owns the program, never null
* @param robotId the robot the program was written for
* @param programText the program text
* @param programTimestamp timestamp of the last change of the program (if it already existed); <code>null</code> if a new program is saved
* @return a pair of (message-key, program). If the program is persisted successfully, the program is NOT null.
*/
public Pair<Key, Program> persistSharedProgramText(String name, User user, Robot robot, String programText, Timestamp timestamp) {
Assert.notNull(name);
Assert.notNull(user);
Assert.notNull(robot);

Program program = loadSharedForUpdate(name, user, robot);
if ( program == null ) {
ProgramDao.LOG.error("update was requested, but no shared program was found");
return Pair.of(Key.PROGRAM_SAVE_ERROR_NO_WRITE_PERMISSION, null);
} else if ( !timestamp.equals(program.getLastChanged()) ) {
ProgramDao.LOG.error("update was requested, timestamps don't match. Has another user updated the program in the meantime?");
return Pair.of(Key.PROGRAM_SAVE_ERROR_OPTIMISTIC_TIMESTAMP_LOCKING, null);
} else {
program.setProgramText(programText);
return Pair.of(Key.PROGRAM_SAVE_SUCCESS, program); // the only legal key if success
}
}

/**
* load a program from the database, identified by its owner, its name (both make up the "business" key of a program)<br>
* The timestamp used for optimistic locking is <b>not</b> checked here. <b>The caller is responsible to do that!</b>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ public enum Key {
PROGRAM_GET_ONE_SUCCESS(),
PROGRAM_GET_ONE_ERROR_NOT_FOUND,
PROGRAM_GET_ONE_ERROR_NOT_LOGGED_IN,
PROGRAM_SAVE_ERROR_NO_PROGRAM_TO_UPDATE_FOUND,
PROGRAM_SAVE_AS_ERROR_PROGRAM_EXISTS,
PROGRAM_SAVE_ERROR_NO_WRITE_PERMISSION,
PROGRAM_SAVE_ERROR_OPTIMISTIC_TIMESTAMP_LOCKING,
PROGRAM_SAVE_ERROR_PROGRAM_TO_UPDATE_NOT_FOUND,
PROGRAM_SAVE_SUCCESS,
PROGRAM_GET_ALL_SUCCESS,
PROGRAM_DELETE_SUCCESS,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,19 @@ public Response command(@OraData HttpSessionState httpSessionState, JSONObject f
AccessRightProcessor upp = new AccessRightProcessor(dbSession, httpSessionState);
UserProcessor up = new UserProcessor(dbSession, httpSessionState);

if ( cmd.equals("saveP") ) {
if ( cmd.equals("saveP") || cmd.equals("saveAsP") ) {
String programName = request.getString("name");
String programText = request.getString("program");
Long timestamp = request.getLong("timestamp");
Timestamp programTimestamp = new Timestamp(timestamp);
boolean isShared = request.optBoolean("shared", false);
Program program = pp.updateProgram(programName, userId, robotId, programText, programTimestamp, !isShared);
Program program;
if ( cmd.equals("saveP") ) {
// update an already existing program
Long timestamp = request.getLong("timestamp");
Timestamp programTimestamp = new Timestamp(timestamp);
boolean isShared = request.optBoolean("shared", false);
program = pp.persistProgramText(programName, userId, robotId, programText, programTimestamp, !isShared);
} else {
program = pp.persistProgramText(programName, userId, robotId, programText, null, true);
}
if ( pp.isOk() ) {
if ( program != null ) {
response.put("lastChanged", program.getLastChanged());
Expand All @@ -115,18 +121,6 @@ public Response command(@OraData HttpSessionState httpSessionState, JSONObject f
forMessages.setSuccess(Key.COMPILERWORKFLOW_PROGRAM_GENERATION_SUCCESS);
}
Util.addResultInfo(response, forMessages);
} else if ( cmd.equals("saveAsP") ) {
String programName = request.getString("name");
String programText = request.getString("program");
Timestamp programTimestamp = new Timestamp(0);
pp.updateProgram(programName, userId, robotId, programText, programTimestamp, true);
if ( pp.isOk() ) {
Program program = pp.getProgram(programName, userId, robotId);
if ( program != null ) {
response.put("lastChanged", program.getLastChanged());
}
}
Util.addResultInfo(response, pp);

} else if ( cmd.equals("loadP") && (httpSessionState.isUserLoggedIn() || request.getString("owner").equals("Roberta")) ) {
String programName = request.getString("name");
Expand Down
Loading

0 comments on commit ddc5765

Please sign in to comment.