// Copyright 2004-2014 Jim Voris
//
// 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 com.qumasoft.qvcslib;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Store check in comments in a property file. This is used as a simple way to allow the user to cycle through the most recent
* check in comments.
* @author Jim Voris
*/
public final class CheckInCommentProperties extends QumaProperties {
// Create our logger object
private static final Logger LOGGER = Logger.getLogger("com.qumasoft.qvcslib");
private static final String MAXIMUM_COMMENT_COUNT = "MaxCommentCount";
private static final int MAXIMUM_COMMENT_COUNT_VALUE = 10;
private static final String COMMENT_COUNT = "CommentCount";
private static final String CHECKIN_COMMENT = "CheckInComment";
private List<String> commentArray;
private int maximumCommentCount;
/**
* Creates a new instance of CheckInCommentProperties.
* @param userName the QVCS user name.
*/
public CheckInCommentProperties(String userName) {
setPropertyFileName(System.getProperty("user.dir")
+ File.separator
+ QVCSConstants.QVCS_USER_DATA_DIRECTORY
+ File.separator
+ QVCSConstants.QVCS_CHECKIN_COMMENTS_PREFIX
+ userName
+ ".properties");
try {
commentArray = new ArrayList<>(MAXIMUM_COMMENT_COUNT_VALUE);
loadProperties(getPropertyFileName());
} catch (QVCSException e) {
// Catch any exception. If the property file is missing, we'll just go
// with the defaults.
LOGGER.log(Level.WARNING, Utility.expandStackTraceToString(e));
}
}
private synchronized void loadProperties(String propertyFilename) throws QVCSException {
FileInputStream inStream = null;
java.util.Properties defaultProperties = new java.util.Properties();
// Define some default values
defaultProperties.put(MAXIMUM_COMMENT_COUNT, "10");
defaultProperties.put(COMMENT_COUNT, "0");
setActualProperties(new java.util.Properties(defaultProperties));
try {
inStream = new FileInputStream(new File(propertyFilename));
getActualProperties().load(inStream);
populateCommentArray();
maximumCommentCount = getMaximumCommentCount();
} catch (IOException e) {
LOGGER.log(Level.WARNING, "Checkin comments file not found: " + propertyFilename);
} finally {
if (inStream != null) {
try {
inStream.close();
} catch (IOException e) {
LOGGER.log(Level.WARNING, "Exception in closing check-in comments properties file: " + propertyFilename + ". Exception: " + e.getClass().toString() + ": "
+ e.getLocalizedMessage());
}
}
}
}
/**
* Get the maximum number of comments.
* @return the maximum number of comments.
*/
public synchronized int getMaximumCommentCount() {
return getIntegerValue(MAXIMUM_COMMENT_COUNT, MAXIMUM_COMMENT_COUNT_VALUE);
}
/**
* Set the maximum number of comments.
* @param maxCommentCount the maximum number of comments.
*/
public synchronized void setMaximumCommentCount(int maxCommentCount) {
setIntegerValue(MAXIMUM_COMMENT_COUNT, maxCommentCount);
this.maximumCommentCount = maxCommentCount;
}
/**
* Get the number of comments.
* @return the number of comments.
*/
public synchronized int getCommentCount() {
return getIntegerValue(COMMENT_COUNT, 0);
}
private synchronized String localGetCheckInComment(int index) {
String tag = getCommentTag(index);
return getStringValue(tag);
}
/**
* Get the given checkin comment.
* @param index the index of the comment we are interested in.
* @return the checking comment for the given index.
*/
public synchronized String getCheckInComment(int index) {
String checkinComment = null;
if (index < commentArray.size()) {
checkinComment = commentArray.get(index);
}
return checkinComment;
}
/**
* Add a checkin comment.
* @param checkInComment a checkin comment.
*/
public synchronized void addCheckInComment(String checkInComment) {
List<String> newCommentArray;
// See if the comment is already present.
for (int i = 0; i < commentArray.size(); i++) {
String existingComment = commentArray.get(i);
if (checkInComment.equals(existingComment)) {
// If the comment is already at the beginning, we don't need
// to do anything.
if (i == 0) {
return;
}
// We need a new container...
newCommentArray = new ArrayList<>(commentArray.size() + 1);
// Move this comment to the front.
newCommentArray.add(0, existingComment);
for (int j = 0; j < commentArray.size(); j++) {
if (i == j) {
continue;
}
newCommentArray.add(commentArray.get(j));
}
commentArray = newCommentArray;
return;
}
}
// We have a new comment, so we need a new container...
newCommentArray = new ArrayList<>(commentArray.size() + 1);
// Comment does not exist yet. Put it first.
newCommentArray.add(0, checkInComment);
// Copy the remaining existing comments to the new container.
int commentCount;
if (commentArray.size() < (maximumCommentCount - 1)) {
commentCount = commentArray.size();
} else {
commentCount = maximumCommentCount - 1;
}
for (int i = 0; i < commentCount; i++) {
newCommentArray.add(commentArray.get(i));
}
commentArray = newCommentArray;
}
/**
* Write the comments to disk.
*/
public synchronized void saveProperties() {
FileOutputStream outStream = null;
if (getActualProperties() != null) {
try {
// Make sure the maximum comment count is in the property container.
setIntegerValue(MAXIMUM_COMMENT_COUNT, maximumCommentCount);
// Limit the comment count to what the user says the max should be.
int commentCount;
if (commentArray.size() > getMaximumCommentCount()) {
commentCount = getMaximumCommentCount();
} else {
commentCount = commentArray.size();
}
// Put the number of comments into the property container.
setIntegerValue(COMMENT_COUNT, commentCount);
// Put the comment strings into the property container.
for (int i = 0; i < commentCount; i++) {
setStringValue(getCommentTag(i), commentArray.get(i));
}
outStream = new FileOutputStream(new File(getPropertyFileName()));
// Write the properties to the property file.
getActualProperties().store(outStream, "QVCS CheckIn Comments for user: " + System.getProperty("user.name"));
} catch (IOException e) {
// Catch any exception. If the property file is missing, we'll just go
// with the defaults.
LOGGER.log(Level.WARNING, Utility.expandStackTraceToString(e));
} finally {
if (outStream != null) {
try {
outStream.close();
} catch (IOException e) {
LOGGER.log(Level.WARNING, "Exception in closing check-in comments properties file: " + getPropertyFileName() + ". Exception: " + e.getClass().toString()
+ ": " + e.getLocalizedMessage());
}
}
}
}
}
private synchronized void populateCommentArray() {
commentArray = new ArrayList<>();
int commentCount = getCommentCount();
for (int i = 0; i < commentCount; i++) {
commentArray.add(i, localGetCheckInComment(i));
}
}
private String getCommentTag(int index) {
return CHECKIN_COMMENT + Integer.toString(index);
}
}