diff --git a/.gitignore b/.gitignore index 883d601..f5fabe2 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ target/ .project .settings/ .classpath +.DS_Store diff --git a/net.sf.redmine_mylyn.api/.settings/org.eclipse.jdt.core.prefs b/net.sf.redmine_mylyn.api/.settings/org.eclipse.jdt.core.prefs index d38636c..8000cd6 100644 --- a/net.sf.redmine_mylyn.api/.settings/org.eclipse.jdt.core.prefs +++ b/net.sf.redmine_mylyn.api/.settings/org.eclipse.jdt.core.prefs @@ -1,4 +1,3 @@ -#Sun May 30 17:51:26 CEST 2010 eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 diff --git a/net.sf.redmine_mylyn.api/META-INF/MANIFEST.MF b/net.sf.redmine_mylyn.api/META-INF/MANIFEST.MF index a17d922..004daf5 100644 --- a/net.sf.redmine_mylyn.api/META-INF/MANIFEST.MF +++ b/net.sf.redmine_mylyn.api/META-INF/MANIFEST.MF @@ -2,10 +2,10 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: net.sf.redmine_mylyn.api;singleton:=true -Bundle-Version: 0.4.0.qualifier +Bundle-Version: 0.4.1.qualifier Bundle-Vendor: %Bundle-Vendor Require-Bundle: org.eclipse.core.runtime;bundle-version="3.5.0", - net.sf.redmine_mylyn.common;bundle-version="0.4.0", + net.sf.redmine_mylyn.common;bundle-version="0.4.1", org.json;bundle-version="1.0.0", org.eclipse.mylyn.commons.net;bundle-version="3.5.0" Bundle-RequiredExecutionEnvironment: JavaSE-1.6 diff --git a/net.sf.redmine_mylyn.api/pom.xml b/net.sf.redmine_mylyn.api/pom.xml index d391421..5a059e3 100644 --- a/net.sf.redmine_mylyn.api/pom.xml +++ b/net.sf.redmine_mylyn.api/pom.xml @@ -7,7 +7,7 @@ net.sf.redmine_mylyn net.sf.redmine_mylyn.parent - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT net.sf.redmine_mylyn.api diff --git a/net.sf.redmine_mylyn.api/src/net/sf/redmine_mylyn/api/client/IRedmineApiClient.java b/net.sf.redmine_mylyn.api/src/net/sf/redmine_mylyn/api/client/IRedmineApiClient.java index a62a091..a6173de 100644 --- a/net.sf.redmine_mylyn.api/src/net/sf/redmine_mylyn/api/client/IRedmineApiClient.java +++ b/net.sf.redmine_mylyn.api/src/net/sf/redmine_mylyn/api/client/IRedmineApiClient.java @@ -20,25 +20,25 @@ public interface IRedmineApiClient { public Configuration getConfiguration(); public RedmineServerVersion detectServerVersion(IProgressMonitor monitor) throws RedmineApiErrorException; - + public void updateConfiguration(IProgressMonitor monitor) throws RedmineApiErrorException; - + public int[] getUpdatedIssueIds(int[] issues, Date updatedSince, IProgressMonitor monitor) throws RedmineApiErrorException; - + public Issue getIssue(int id, IProgressMonitor monitor) throws RedmineApiErrorException; - + public Issue[] getIssues(IProgressMonitor monitor, int... issueIds) throws RedmineApiErrorException; - + public Issue[] query(Query query, IProgressMonitor monitor) throws RedmineApiErrorException; - + public Issue createIssue(Issue issue, IRedmineApiErrorCollector errorCollector, IProgressMonitor monitor) throws RedmineApiInvalidDataException, RedmineApiErrorException; - public void updateIssue(Issue issue, String comment, TimeEntry timeEntry, IRedmineApiErrorCollector errorCollector, IProgressMonitor monitor) throws RedmineApiInvalidDataException, RedmineApiErrorException; + public void updateIssue(Issue issue, String comment, Date lastModified, TimeEntry timeEntry, IRedmineApiErrorCollector errorCollector, IProgressMonitor monitor) throws RedmineApiInvalidDataException, RedmineApiErrorException; public void updateIssue(int issueId, Map issueValues, String comment, TimeEntry timeEntry, IRedmineApiErrorCollector errorCollector, IProgressMonitor monitor) throws RedmineApiInvalidDataException, RedmineApiErrorException; public InputStream getAttachmentContent(int attachmentId, String fileName, IProgressMonitor monitor) throws RedmineApiErrorException; - + public void uploadAttachment(int issueId, Attachment attachment, InputStream content, String comment, IRedmineApiErrorCollector errorCollector, IProgressMonitor monitor) throws RedmineApiInvalidDataException, RedmineApiErrorException; } diff --git a/net.sf.redmine_mylyn.api/src/net/sf/redmine_mylyn/api/model/CustomField.java b/net.sf.redmine_mylyn.api/src/net/sf/redmine_mylyn/api/model/CustomField.java index 912da7e..920fe26 100644 --- a/net.sf.redmine_mylyn.api/src/net/sf/redmine_mylyn/api/model/CustomField.java +++ b/net.sf.redmine_mylyn.api/src/net/sf/redmine_mylyn/api/model/CustomField.java @@ -15,78 +15,81 @@ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name="customField", propOrder={ - "type", - "fieldFormat", - "minLength", - "maxLength", - "regexp", - "possibleValues", - "defaultValue", - "isRequired", - "isFilter", - "isForAll"}) + "type", + "fieldFormat", + "minLength", + "maxLength", + "regexp", + "possibleValues", + "defaultValue", + "isRequired", + "isFilter", + "isForAll", +"isMultiple"}) public class CustomField extends Property implements IQueryField { - + private static final long serialVersionUID = 1L; public enum Type {IssueCustomField, TimeEntryCustomField}; public enum Format { @XmlEnumValue("string") - STRING, + STRING, @XmlEnumValue("text") - TEXT, + TEXT, @XmlEnumValue("int") - INT, + INT, @XmlEnumValue("float") - FLOAT, + FLOAT, @XmlEnumValue("list") - LIST, + LIST, @XmlEnumValue("date") - DATE, + DATE, @XmlEnumValue("bool") BOOL, @XmlEnumValue("version") VERSION, @XmlEnumValue("user") USER; - + public String getLabel() { return name().toLowerCase(); } - + public boolean isListType() { return this==LIST || this==VERSION || this==USER; } }; private Type type; - + private Format fieldFormat; - + @XmlElementWrapper(name="possibleValues") @XmlElement(name="possibleValue") private List possibleValues; - + private String regexp; - + private int minLength; private int maxLength; - + private boolean isRequired; - + private boolean isForAll; private boolean isFilter; - + private String defaultValue; + private boolean isMultiple; + public Type getType() { return type; } - public void setType(Type type) { + public void setType(final Type type) { this.type = type; } @@ -94,7 +97,7 @@ public Format getFieldFormat() { return fieldFormat; } - public void setFieldFormat(Format fieldFormat) { + public void setFieldFormat(final Format fieldFormat) { this.fieldFormat = fieldFormat; } @@ -102,7 +105,7 @@ public List getPossibleValues() { return possibleValues; } - public void setPossibleValues(List possibleValues) { + public void setPossibleValues(final List possibleValues) { this.possibleValues = possibleValues; } @@ -110,7 +113,7 @@ public String getRegexp() { return regexp; } - public void setRegexp(String regexp) { + public void setRegexp(final String regexp) { this.regexp = regexp; } @@ -118,7 +121,7 @@ public int getMinLength() { return minLength; } - public void setMinLength(int minLength) { + public void setMinLength(final int minLength) { this.minLength = minLength; } @@ -126,7 +129,7 @@ public int getMaxLength() { return maxLength; } - public void setMaxLength(int maxLength) { + public void setMaxLength(final int maxLength) { this.maxLength = maxLength; } @@ -134,7 +137,7 @@ public boolean isRequired() { return isRequired; } - public void setRequired(boolean isRequired) { + public void setRequired(final boolean isRequired) { this.isRequired = isRequired; } @@ -142,7 +145,7 @@ public boolean isForAll() { return isForAll; } - public void setForAll(boolean isForAll) { + public void setForAll(final boolean isForAll) { this.isForAll = isForAll; } @@ -150,7 +153,7 @@ public boolean isFilter() { return isFilter && getFieldFormat()!=Format.USER && getFieldFormat()!=Format.VERSION; } - public void setFilter(boolean isFilter) { + public void setFilter(final boolean isFilter) { this.isFilter = isFilter; } @@ -158,7 +161,7 @@ public String getDefaultValue() { return defaultValue; } - public void setDefaultValue(String defaultValue) { + public void setDefaultValue(final String defaultValue) { this.defaultValue = defaultValue; } @@ -176,7 +179,7 @@ public String getLabel() { public boolean isCrossProjectUsable() { return isForAll; } - + public QueryField getQueryField() { if(isFilter()) { switch (getFieldFormat()) { @@ -187,10 +190,14 @@ public QueryField getQueryField() { case TEXT: return QueryField.TEXT_TYPE; case INT: return QueryField.INT_TYPE; case FLOAT: return QueryField.FLOAT_TYPE; - + default: return null; } } return null; } + + public boolean isMultiple() { + return isMultiple; + } } diff --git a/net.sf.redmine_mylyn.api/src/net/sf/redmine_mylyn/api/model/container/CustomValues.java b/net.sf.redmine_mylyn.api/src/net/sf/redmine_mylyn/api/model/container/CustomValues.java index 7aaa409..71c4b38 100644 --- a/net.sf.redmine_mylyn.api/src/net/sf/redmine_mylyn/api/model/container/CustomValues.java +++ b/net.sf.redmine_mylyn.api/src/net/sf/redmine_mylyn/api/model/container/CustomValues.java @@ -11,44 +11,48 @@ import net.sf.redmine_mylyn.api.model.CustomValue; +import org.json.JSONArray; +import org.json.JSONException; + @XmlType(name="customValues") @XmlAccessorType(XmlAccessType.NONE) public class CustomValues extends AbstractTypedContainer { private List customValues; - + private HashMap byCustomFieldId; - + @Override @XmlElement(name="customValue") protected List getModifiableList() { if(customValues==null) { byCustomFieldId = new HashMap(); - + customValues = new ArrayList() { private static final long serialVersionUID = 1L; - - public boolean add(CustomValue e) { + + @Override + public boolean add(final CustomValue e) { if(super.add(e)) { byCustomFieldId.put(Integer.valueOf(e.getCustomFieldId()), e); return true; } return false; }; - + }; } return customValues; } - - public CustomValue getByCustomFieldId(int customFieldId) { + + public CustomValue getByCustomFieldId(final int customFieldId) { if(byCustomFieldId!=null) { return byCustomFieldId.get(Integer.valueOf(customFieldId)); } return null; } - - public void setCustomValue(int customFieldId, String value) { + + public void setCustomValue(final int customFieldId, final String value) { CustomValue customValue= getByCustomFieldId(Integer.valueOf(customFieldId)); if(customValue==null) { customValue = new CustomValue(); @@ -56,7 +60,20 @@ public void setCustomValue(int customFieldId, String value) { customValue.setValue(value); getModifiableList().add(customValue); } else { - customValue.setValue(value); + final String existingValue = customValue.getValue(); + if (existingValue == null || existingValue.isEmpty()) { + customValue.setValue(value); + } else { + JSONArray array; + try { + array = new JSONArray(existingValue); + } catch (final JSONException e) { + array = new JSONArray(); + array.put(existingValue); + } + array.put(value); + customValue.setValue(array.toString()); + } } } diff --git a/net.sf.redmine_mylyn.api/src/net/sf/redmine_mylyn/api/model/container/Users.java b/net.sf.redmine_mylyn.api/src/net/sf/redmine_mylyn/api/model/container/Users.java index 5b4dbd7..202a32e 100644 --- a/net.sf.redmine_mylyn.api/src/net/sf/redmine_mylyn/api/model/container/Users.java +++ b/net.sf.redmine_mylyn.api/src/net/sf/redmine_mylyn/api/model/container/Users.java @@ -18,10 +18,10 @@ public class Users extends AbstractPropertyContainer { private static final long serialVersionUID = 1L; protected List users; - + protected HashMap usersByLogin; - - + + @Override @XmlElement(name="user") protected List getModifiableList() { @@ -29,10 +29,15 @@ protected List getModifiableList() { users = new ArrayList() { private static final long serialVersionUID = 1L; - + @Override - public boolean add(User e) { - getUsersByLogin().put(e.getLogin(), e); + public boolean add(final User e) { + final String login = e.getLogin(); + if (login.isEmpty()) { + getUsersByLogin().put(e.getName(), e); + } else { + getUsersByLogin().put(login, e); + } return super.add(e); } }; @@ -40,7 +45,7 @@ public boolean add(User e) { return users; } - public User getByLogin(String login) { + public User getByLogin(final String login) { return usersByLogin==null ? null : usersByLogin.get(login); } @@ -50,5 +55,5 @@ protected HashMap getUsersByLogin() { } return usersByLogin; } - + } diff --git a/net.sf.redmine_mylyn.api/src/net/sf/redmine_mylyn/internal/api/Messages.java b/net.sf.redmine_mylyn.api/src/net/sf/redmine_mylyn/internal/api/Messages.java index 7757b65..a1685c8 100644 --- a/net.sf.redmine_mylyn.api/src/net/sf/redmine_mylyn/internal/api/Messages.java +++ b/net.sf.redmine_mylyn.api/src/net/sf/redmine_mylyn/internal/api/Messages.java @@ -20,6 +20,7 @@ public class Messages extends NLS { public static String ERRMSG_METHOD_EXECUTION_FAILED; public static String ERRMSG_METHOD_EXECUTION_FAILED_INVALID_ENCODING; public static String ERRMSG_METHOD_EXECUTION_FAILED_X; + public static String ERRMSG_METHOD_EXECUTION_FAILED_MIDAIR_CONFLICT; public static String ERRMSG_MISSING_CREDENTIALS_SYNCHRONIZATION_FAILED; public static String ERRMSG_PARAMETER_X_INVALID_INTEGER; public static String ERRMSG_PARAMETER_X_INVALID_MILISEC; diff --git a/net.sf.redmine_mylyn.api/src/net/sf/redmine_mylyn/internal/api/client/Api_2_7_ClientImpl.java b/net.sf.redmine_mylyn.api/src/net/sf/redmine_mylyn/internal/api/client/Api_2_7_ClientImpl.java index 08dbb16..2b30c11 100644 --- a/net.sf.redmine_mylyn.api/src/net/sf/redmine_mylyn/internal/api/client/Api_2_7_ClientImpl.java +++ b/net.sf.redmine_mylyn.api/src/net/sf/redmine_mylyn/internal/api/client/Api_2_7_ClientImpl.java @@ -2,6 +2,7 @@ import java.io.InputStream; import java.io.UnsupportedEncodingException; +import java.text.DateFormat; import java.util.Arrays; import java.util.Date; import java.util.HashMap; @@ -79,38 +80,38 @@ public class Api_2_7_ClientImpl extends AbstractClient { private final static String URL_QUERY = "/mylyn/issues"; //$NON-NLS-1$ private final static String URL_UPDATE_ISSUE = "/issues/%d.xml"; //$NON-NLS-1$ - + private final static String URL_GET_ATTACHMENT = "/mylyn/attachment/%d/%s"; //$NON-NLS-1$ private final static String URL_GET_AUTHENTICITY_TOKEN = "/mylyn/token"; //$NON-NLS-1$ - + private final static String HEADER_CSRF_TOKEN = "X-CSRF-Token"; - + private Map>> parserByClass; - + private SettingsParser settingsParser; private TypedParser updatedIssuesParser; private IssueParser issueParser; private IssuesParser issuesParser; private TypedParser versionParser; - + private SubmitedIssueParser submitIssueParser; private AttachmentParser attachmentParser; private StringParser stringParser; - - private Configuration configuration; - - Api_2_7_ClientImpl(IRedmineApiWebHelper webHelper) { + + private final Configuration configuration; + + Api_2_7_ClientImpl(final IRedmineApiWebHelper webHelper) { this(webHelper, new Configuration()); } - public Api_2_7_ClientImpl(IRedmineApiWebHelper webHelper, Configuration initialConfiguration) { + public Api_2_7_ClientImpl(final IRedmineApiWebHelper webHelper, final Configuration initialConfiguration) { super(webHelper); - - this.configuration = initialConfiguration; + + configuration = initialConfiguration; buildParser(); } - + @Override public Configuration getConfiguration() { return configuration; @@ -121,8 +122,8 @@ public RedmineServerVersion detectServerVersion(IProgressMonitor monitor) throws monitor = Policy.monitorFor(monitor); monitor.beginTask(Messages.PROGRESS_DETECT_REDMINE_VERSION, 1); - GetMethod method = new GetMethod(URL_SERVER_VERSION); - RedmineServerVersion version = executeMethod(method, versionParser, monitor); + final GetMethod method = new GetMethod(URL_SERVER_VERSION); + final RedmineServerVersion version = executeMethod(method, versionParser, monitor); if(monitor.isCanceled()) { throw new OperationCanceledException(); @@ -132,19 +133,19 @@ public RedmineServerVersion detectServerVersion(IProgressMonitor monitor) throws return version; } - + @Override public void updateConfiguration(IProgressMonitor monitor) throws RedmineApiErrorException { monitor = Policy.monitorFor(monitor); - Configuration conf = new Configuration(); - + final Configuration conf = new Configuration(); + monitor.beginTask(Messages.PROGRESS_UPDATING_ATTRIBUTES, parserByClass.size()+1); GetMethod method = null; - - for (Entry>> entry : parserByClass.entrySet()) { + + for (final Entry>> entry : parserByClass.entrySet()) { method = new GetMethod(entry.getKey()); - AbstractPropertyContainer propCt = executeMethod(method, entry.getValue(), monitor); + final AbstractPropertyContainer propCt = executeMethod(method, entry.getValue(), monitor); if(monitor.isCanceled()) { throw new OperationCanceledException(); @@ -161,124 +162,124 @@ public void updateConfiguration(IProgressMonitor monitor) throws RedmineApiError } else { monitor.worked(1); } - + getConfiguration().copy(conf); } - + @Override - public int[] getUpdatedIssueIds(int[] issues, Date updatedSince, IProgressMonitor monitor) throws RedmineApiErrorException { + public int[] getUpdatedIssueIds(final int[] issues, final Date updatedSince, IProgressMonitor monitor) throws RedmineApiErrorException { if (issues==null || issues.length==0) { return null; } - + long unixtime = updatedSince.getTime()/1000l; //workaround: bug in redmine plugin unixtime += 1l; - + monitor = Policy.monitorFor(monitor); monitor.beginTask(Messages.PROGRESS_SEARCH_UPDATED_ISSUES, 1); - String uri = String.format(URL_ISSUES_UPDATED, Arrays.toString(issues).replaceAll("[\\[\\] ]", ""), unixtime); //$NON-NLS-1$ //$NON-NLS-2$ - GetMethod method = new GetMethod(uri); - - UpdatedIssuesType result = executeMethod(method, updatedIssuesParser, monitor); + final String uri = String.format(URL_ISSUES_UPDATED, Arrays.toString(issues).replaceAll("[\\[\\] ]", ""), unixtime); //$NON-NLS-1$ //$NON-NLS-2$ + final GetMethod method = new GetMethod(uri); + + final UpdatedIssuesType result = executeMethod(method, updatedIssuesParser, monitor); if(monitor.isCanceled()) { throw new OperationCanceledException(); } else { monitor.worked(1); } - + return result.updatedIssueIds; } - + @Override - public Issue getIssue(int id, IProgressMonitor monitor) throws RedmineApiErrorException { + public Issue getIssue(final int id, IProgressMonitor monitor) throws RedmineApiErrorException { if(id < 1) { return null; } - + monitor = Policy.monitorFor(monitor); monitor.beginTask(Messages.PROGRESS_FETCH_ISSUE, 1); - String uri = String.format(URL_ISSUE, id); - GetMethod method = new GetMethod(uri); - - Issue issue = executeMethod(method, issueParser, monitor); + final String uri = String.format(URL_ISSUE, id); + final GetMethod method = new GetMethod(uri); + + final Issue issue = executeMethod(method, issueParser, monitor); if(monitor.isCanceled()) { throw new OperationCanceledException(); } else { monitor.worked(1); } - + return issue; } - + @Override - public Issue[] getIssues(IProgressMonitor monitor, int... issueIds) throws RedmineApiErrorException { + public Issue[] getIssues(IProgressMonitor monitor, final int... issueIds) throws RedmineApiErrorException { if (issueIds==null || issueIds.length==0) { return null; } - + monitor = Policy.monitorFor(monitor); monitor.beginTask(Messages.PROGRESS_FETCH_ISSUES, 1); - String uri = String.format(URL_ISSUES_LIST, Arrays.toString(issueIds).replaceAll("[\\[\\] ]", "")); //$NON-NLS-1$ //$NON-NLS-2$ - GetMethod method = new GetMethod(uri); - - Issues issues = executeMethod(method, issuesParser, monitor); + final String uri = String.format(URL_ISSUES_LIST, Arrays.toString(issueIds).replaceAll("[\\[\\] ]", "")); //$NON-NLS-1$ //$NON-NLS-2$ + final GetMethod method = new GetMethod(uri); + + final Issues issues = executeMethod(method, issuesParser, monitor); if(monitor.isCanceled()) { throw new OperationCanceledException(); } else { monitor.worked(1); } - + return issues.getAll().toArray(new Issue[issues.getAll().size()]); } @Override - public Issue[] query(Query query, IProgressMonitor monitor) throws RedmineApiErrorException { + public Issue[] query(final Query query, IProgressMonitor monitor) throws RedmineApiErrorException { monitor = Policy.monitorFor(monitor); monitor.beginTask(Messages.PROGRESS_EXECUTE_QUERY, 1); - GetMethod method = new GetMethod(URL_QUERY); - List params = query.getParams(); - + final GetMethod method = new GetMethod(URL_QUERY); + final List params = query.getParams(); + if(params.size()>0) { method.setQueryString(params.toArray(new NameValuePair[params.size()])); } - Issues partialIssues = executeMethod(method, issuesParser, monitor); + final Issues partialIssues = executeMethod(method, issuesParser, monitor); if(monitor.isCanceled()) { throw new OperationCanceledException(); } else { monitor.worked(1); } - + return partialIssues.getAll().toArray(new Issue[partialIssues.getAll().size()]); } @Override - public Issue createIssue(Issue issue, IRedmineApiErrorCollector errorCollector, IProgressMonitor monitor) throws RedmineApiInvalidDataException, RedmineApiErrorException { + public Issue createIssue(final Issue issue, final IRedmineApiErrorCollector errorCollector, IProgressMonitor monitor) throws RedmineApiInvalidDataException, RedmineApiErrorException { monitor = Policy.monitorFor(monitor); monitor.beginTask(Messages.PROGRESS_UPLOAD_TASK, 1); - - PostMethod method = new PostMethod("/issues.xml"); //$NON-NLS-1$ + + final PostMethod method = new PostMethod("/issues.xml"); //$NON-NLS-1$ try { //Workaround: remote method CREATE dosn't support API-Keys, we need a session - String token = getAuthenticityToken(monitor); - + final String token = getAuthenticityToken(monitor); + method.setRequestEntity(new IssueRequestEntity(issue)); method.addRequestHeader(HEADER_CSRF_TOKEN, token); - - } catch (UnsupportedEncodingException e) { - throw new RedmineApiErrorException(Messages.ERRMSG_METHOD_EXECUTION_FAILED_INVALID_ENCODING, e, "UTF-8"); //$NON-NLS-2$ //$NON-NLS-1$ + + } catch (final UnsupportedEncodingException e) { + throw new RedmineApiErrorException(Messages.ERRMSG_METHOD_EXECUTION_FAILED_INVALID_ENCODING, e, "UTF-8"); //$NON-NLS-1$ } - - Object response = executeMethod(method, submitIssueParser, monitor, HttpStatus.SC_CREATED, HttpStatus.SC_UNPROCESSABLE_ENTITY); - + + final Object response = executeMethod(method, submitIssueParser, monitor, HttpStatus.SC_CREATED, HttpStatus.SC_UNPROCESSABLE_ENTITY); + if(monitor.isCanceled()) { throw new OperationCanceledException(); } else { @@ -288,25 +289,25 @@ public Issue createIssue(Issue issue, IRedmineApiErrorCollector errorCollector, if(response instanceof PartialIssueType) { return ((PartialIssueType)response).toIssue(); } else { - SubmitError error = (SubmitError)response; - for (String errMsg : error.errors) { + final SubmitError error = (SubmitError)response; + for (final String errMsg : error.errors) { errorCollector.accept(errMsg); } - + throw new RedmineApiInvalidDataException(); } } - + @Override - public void updateIssue(int issueId, Map issueValues, String comment, TimeEntry timeEntry, IRedmineApiErrorCollector errorCollector, IProgressMonitor monitor) throws RedmineApiInvalidDataException, RedmineApiErrorException { + public void updateIssue(final int issueId, final Map issueValues, final String comment, final TimeEntry timeEntry, final IRedmineApiErrorCollector errorCollector, IProgressMonitor monitor) throws RedmineApiInvalidDataException, RedmineApiErrorException { monitor = Policy.monitorFor(monitor); monitor.beginTask(Messages.PROGRESS_UPLOAD_TASK, 1); try { issueValues.put(RedmineApiIssueProperty.NOTES, comment); updateIssue(issueId, new IssueRequestEntity(issueValues, comment, timeEntry), errorCollector, monitor); - } catch (UnsupportedEncodingException e) { - throw new RedmineApiErrorException(Messages.ERRMSG_METHOD_EXECUTION_FAILED_INVALID_ENCODING, e, "UTF-8"); //$NON-NLS-2$ //$NON-NLS-1$ + } catch (final UnsupportedEncodingException e) { + throw new RedmineApiErrorException(Messages.ERRMSG_METHOD_EXECUTION_FAILED_INVALID_ENCODING, e, "UTF-8"); //$NON-NLS-1$ } finally { if(monitor.isCanceled()) { throw new OperationCanceledException(); @@ -315,17 +316,26 @@ public void updateIssue(int issueId, Map issueV } } } - + @Override - public void updateIssue(Issue issue, String comment, TimeEntry timeEntry, IRedmineApiErrorCollector errorCollector, IProgressMonitor monitor) throws RedmineApiInvalidDataException, RedmineApiErrorException { + public void updateIssue(final Issue issue, final String comment, final Date lastModified, final TimeEntry timeEntry, final IRedmineApiErrorCollector errorCollector, IProgressMonitor monitor) throws RedmineApiInvalidDataException, RedmineApiErrorException { monitor = Policy.monitorFor(monitor); monitor.beginTask(Messages.PROGRESS_UPLOAD_TASK, 1); try { - issue.setNotes(comment); - updateIssue(issue.getId(), new IssueRequestEntity(issue, comment, timeEntry), errorCollector, monitor); - } catch (UnsupportedEncodingException e) { - throw new RedmineApiErrorException(Messages.ERRMSG_METHOD_EXECUTION_FAILED_INVALID_ENCODING, e, "UTF-8"); //$NON-NLS-2$ //$NON-NLS-1$ + final int[] updatedIssueIds = getUpdatedIssueIds( + new int[] { issue.getId(), }, lastModified, monitor); + if (updatedIssueIds.length == 0) { + issue.setUpdatedOn(null); + issue.setNotes(comment); + updateIssue(issue.getId(), new IssueRequestEntity(issue, + comment, timeEntry), errorCollector, monitor); + } else { + throw new RedmineApiErrorException( + Messages.ERRMSG_METHOD_EXECUTION_FAILED_MIDAIR_CONFLICT, DateFormat.getInstance().format(lastModified)); + } + } catch (final UnsupportedEncodingException e) { + throw new RedmineApiErrorException(Messages.ERRMSG_METHOD_EXECUTION_FAILED_INVALID_ENCODING, e, "UTF-8"); //$NON-NLS-1$ } finally { if(monitor.isCanceled()) { throw new OperationCanceledException(); @@ -334,40 +344,40 @@ public void updateIssue(Issue issue, String comment, TimeEntry timeEntry, IRedmi } } } - - private void updateIssue(int issueId, IssueRequestEntity requestEntity, IRedmineApiErrorCollector errorCollector, IProgressMonitor monitor) throws RedmineApiInvalidDataException, RedmineApiErrorException { + + private void updateIssue(final int issueId, final IssueRequestEntity requestEntity, final IRedmineApiErrorCollector errorCollector, final IProgressMonitor monitor) throws RedmineApiInvalidDataException, RedmineApiErrorException { //Workaround: remote method UPDATE dosn't support API-Keys, we need a session - String token = getAuthenticityToken(monitor); - - PutMethod method = new PutMethod(String.format(URL_UPDATE_ISSUE, issueId)); + final String token = getAuthenticityToken(monitor); + + final PutMethod method = new PutMethod(String.format(URL_UPDATE_ISSUE, issueId)); method.setRequestEntity(requestEntity); method.addRequestHeader(HEADER_CSRF_TOKEN, token); - - Object response = executeMethod(method, submitIssueParser, monitor, HttpStatus.SC_OK, HttpStatus.SC_UNPROCESSABLE_ENTITY); - + + final Object response = executeMethod(method, submitIssueParser, monitor, HttpStatus.SC_OK, HttpStatus.SC_UNPROCESSABLE_ENTITY); + if(response instanceof SubmitError) { - SubmitError error = (SubmitError)response; - for (String errMsg : error.errors) { + final SubmitError error = (SubmitError)response; + for (final String errMsg : error.errors) { errorCollector.accept(errMsg); } - + throw new RedmineApiInvalidDataException(); } } - + @Override - public InputStream getAttachmentContent(int attachmentId, String fileName, IProgressMonitor monitor) throws RedmineApiErrorException { + public InputStream getAttachmentContent(final int attachmentId, final String fileName, IProgressMonitor monitor) throws RedmineApiErrorException { monitor = Policy.monitorFor(monitor); monitor.beginTask(Messages.PROGRESS_DOWNLOAD_ATTACHMENT, 1); - + //WOrkaround: Attachments::download dosn't support API-AUTH - this starts a session - String token = getAuthenticityToken(monitor); + final String token = getAuthenticityToken(monitor); if(token==null) { throw new RedmineApiRemoteException(Messages.ERRMSG_AUTH_TOKEN_REQUEST_FAILED); } - - GetMethod method = new GetMethod(String.format(URL_GET_ATTACHMENT, attachmentId, fileName)); - InputStream attachment = executeMethod(method, attachmentParser, monitor, HttpStatus.SC_OK, HttpStatus.SC_NOT_FOUND); + + final GetMethod method = new GetMethod(String.format(URL_GET_ATTACHMENT, attachmentId, fileName)); + final InputStream attachment = executeMethod(method, attachmentParser, monitor, HttpStatus.SC_OK, HttpStatus.SC_NOT_FOUND); if(monitor.isCanceled()) { throw new OperationCanceledException(); @@ -377,39 +387,41 @@ public InputStream getAttachmentContent(int attachmentId, String fileName, IProg return attachment; } - - public void uploadAttachment(int issueId, final Attachment attachment, final InputStream content, String comment, IRedmineApiErrorCollector errorCollector, IProgressMonitor monitor) throws RedmineApiInvalidDataException, RedmineApiErrorException { + + @Override + public void uploadAttachment(final int issueId, final Attachment attachment, final InputStream content, final String comment, final IRedmineApiErrorCollector errorCollector, IProgressMonitor monitor) throws RedmineApiInvalidDataException, RedmineApiErrorException { monitor = Policy.monitorFor(monitor); monitor.beginTask(Messages.PROGRESS_UPLOAD_ATTACHMENT, 1); - + Object response = null; - - String token = getAuthenticityToken(monitor); + + final String token = getAuthenticityToken(monitor); if(token==null) { throw new RedmineApiRemoteException(Messages.ERRMSG_AUTH_TOKEN_REQUEST_FAILED); } - + try { - PutMethod method = new PutMethod(String.format(URL_UPDATE_ISSUE, issueId)); - - Part[] parts = new Part[4]; + final PutMethod method = new PutMethod(String.format(URL_UPDATE_ISSUE, issueId)); + + final Part[] parts = new Part[4]; parts[0] = new StringPart("authenticity_token", token, characterEncoding); //$NON-NLS-1$ parts[1] = new StringPart("attachments[1][description]", attachment.getDescription(), characterEncoding); //$NON-NLS-1$ parts[2] = new StringPart("notes", comment, characterEncoding); //$NON-NLS-1$ - + //Workaround: http://rack.lighthouseapp.com/projects/22435/tickets/79-multipart-handling-incorrectly-assuming-file-upload for(int i=2;i>=0;i--) { ((StringPart)parts[i]).setContentType(null); } - + parts[3] = new FilePart("attachments[1][file]", new AttachmentPartSource(attachment, content), attachment.getContentType(), null) { //$NON-NLS-1$ //Workaround: avoid 'Content-Type image/png; charset=iso8859-1' + @Override public String getCharSet() { return null; }; }; method.setRequestEntity(new MultipartRequestEntity(parts, method.getParams())); - + response = executeMethod(method, submitIssueParser, monitor, HttpStatus.SC_OK, HttpStatus.SC_UNPROCESSABLE_ENTITY); } finally { if(monitor.isCanceled()) { @@ -418,32 +430,32 @@ public String getCharSet() { monitor.worked(1); } } - + if(response instanceof SubmitError) { - SubmitError error = (SubmitError)response; - for (String errMsg : error.errors) { + final SubmitError error = (SubmitError)response; + for (final String errMsg : error.errors) { errorCollector.accept(errMsg); } - + throw new RedmineApiInvalidDataException(); } } - - private String getAuthenticityToken(IProgressMonitor monitor) throws RedmineApiErrorException { + + private String getAuthenticityToken(final IProgressMonitor monitor) throws RedmineApiErrorException { monitor.beginTask(Messages.PROGRESS_REQUEST_AUTHTOKEN, 1); - - GetMethod method = new GetMethod(URL_GET_AUTHENTICITY_TOKEN); - String token = executeMethod(method, stringParser, monitor); - + + final GetMethod method = new GetMethod(URL_GET_AUTHENTICITY_TOKEN); + final String token = executeMethod(method, stringParser, monitor); + if(monitor.isCanceled()) { throw new OperationCanceledException(); } else { monitor.worked(1); } - + return token; } - + private void buildParser() { parserByClass = new HashMap>>(); parserByClass.put(URL_ISSUE_STATUS, new AttributeParser(IssueStatuses.class)); @@ -455,7 +467,7 @@ private void buildParser() { parserByClass.put(URL_QUERIES, new AttributeParser(Queries.class)); parserByClass.put(URL_PROJECTS, new AttributeParser(Projects.class)); parserByClass.put(URL_VERSIONS, new AttributeParser(Versions.class)); - + settingsParser = new SettingsParser(); updatedIssuesParser = new TypedParser(UpdatedIssuesType.class); issueParser = new IssueParser(getConfiguration()); @@ -466,5 +478,5 @@ private void buildParser() { stringParser = new StringParser(); submitIssueParser = new SubmitedIssueParser(); } - + } diff --git a/net.sf.redmine_mylyn.api/src/net/sf/redmine_mylyn/internal/api/client/IssueRequestEntity.java b/net.sf.redmine_mylyn.api/src/net/sf/redmine_mylyn/internal/api/client/IssueRequestEntity.java index c025518..698d329 100644 --- a/net.sf.redmine_mylyn.api/src/net/sf/redmine_mylyn/internal/api/client/IssueRequestEntity.java +++ b/net.sf.redmine_mylyn.api/src/net/sf/redmine_mylyn/internal/api/client/IssueRequestEntity.java @@ -15,147 +15,153 @@ import net.sf.redmine_mylyn.internal.api.Messages; import org.apache.commons.httpclient.methods.StringRequestEntity; +import org.json.JSONArray; import org.json.JSONException; import org.json.JSONWriter; public class IssueRequestEntity extends StringRequestEntity { - public IssueRequestEntity(Issue issue) throws UnsupportedEncodingException, RedmineApiErrorException { + public IssueRequestEntity(final Issue issue) throws UnsupportedEncodingException, RedmineApiErrorException { super(writeIssue(issue, null, null), "application/json", "UTF-8"); //$NON-NLS-1$ //$NON-NLS-2$ } - public IssueRequestEntity(Issue issue, String comment, TimeEntry timeEntry) throws UnsupportedEncodingException, RedmineApiErrorException { + public IssueRequestEntity(final Issue issue, final String comment, final TimeEntry timeEntry) throws UnsupportedEncodingException, RedmineApiErrorException { super(writeIssue(issue, comment, timeEntry), "application/json", "UTF-8"); //$NON-NLS-1$ //$NON-NLS-2$ } - public IssueRequestEntity(Map issue, String comment, TimeEntry timeEntry) throws UnsupportedEncodingException, RedmineApiErrorException { + public IssueRequestEntity(final Map issue, final String comment, final TimeEntry timeEntry) throws UnsupportedEncodingException, RedmineApiErrorException { super(writeIssue(issue, comment, timeEntry), "application/json", "UTF-8"); //$NON-NLS-1$ //$NON-NLS-2$ } - - private static String writeIssue(Issue issue, String comment, TimeEntry timeEntry) throws RedmineApiErrorException { + + private static String writeIssue(final Issue issue, final String comment, final TimeEntry timeEntry) throws RedmineApiErrorException { try { - StringWriter stringWriter = new StringWriter(); - - JSONWriter jsonWriter = new JSONWriter(stringWriter); - + final StringWriter stringWriter = new StringWriter(); + + final JSONWriter jsonWriter = new JSONWriter(stringWriter); + jsonWriter.object(); writeIssueValues(jsonWriter, issue); writeComment(jsonWriter, comment); writeTimeEntry(jsonWriter, timeEntry); jsonWriter.endObject(); - - + + return stringWriter.toString(); - } catch (JSONException e) { + } catch (final JSONException e) { e.printStackTrace(); throw new RedmineApiErrorException(Messages.ERRMSG_CREATION_OF_SUBMIT_DATA_FAILED, e); } } - - private static String writeIssue(Map issue, String comment, TimeEntry timeEntry) throws RedmineApiErrorException { + + private static String writeIssue(final Map issue, final String comment, final TimeEntry timeEntry) throws RedmineApiErrorException { try { - StringWriter stringWriter = new StringWriter(); - - JSONWriter jsonWriter = new JSONWriter(stringWriter); - + final StringWriter stringWriter = new StringWriter(); + + final JSONWriter jsonWriter = new JSONWriter(stringWriter); + jsonWriter.object(); writeIssueValues(jsonWriter, issue); writeComment(jsonWriter, comment); writeTimeEntry(jsonWriter, timeEntry); jsonWriter.endObject(); - - + + return stringWriter.toString(); - } catch (JSONException e) { + } catch (final JSONException e) { e.printStackTrace(); throw new RedmineApiErrorException(Messages.ERRMSG_CREATION_OF_SUBMIT_DATA_FAILED, e); } } - - private static void writeComment(JSONWriter jsonWriter, String comment) throws JSONException { + + private static void writeComment(final JSONWriter jsonWriter, final String comment) throws JSONException { if(comment!=null && !comment.trim().isEmpty()) { jsonWriter.key("notes").value(comment); //$NON-NLS-1$ } } - private static void writeTimeEntry(JSONWriter jsonWriter, TimeEntry timeEntry) throws JSONException { + private static void writeTimeEntry(final JSONWriter jsonWriter, final TimeEntry timeEntry) throws JSONException { if(timeEntry!=null) { jsonWriter.key("time_entry").object(); //$NON-NLS-1$ - + writeValue(jsonWriter, "hours", ""+timeEntry.getHours()); //$NON-NLS-1$ //$NON-NLS-2$ writeValue(jsonWriter, "activity_id", ""+timeEntry.getActivityId()); //$NON-NLS-1$ //$NON-NLS-2$ writeValue(jsonWriter, "comments", ""+timeEntry.getComments()); //$NON-NLS-1$ //$NON-NLS-2$ writeCustomValues(jsonWriter, timeEntry.getCustomValues()); writeMappedValues(jsonWriter, timeEntry.getExtensionValues()); - + jsonWriter.endObject(); - } + } } - private static void writeIssueValues(JSONWriter jsonWriter, Issue issue) throws JSONException { + private static void writeIssueValues(final JSONWriter jsonWriter, final Issue issue) throws JSONException { jsonWriter.key("issue").object(); //$NON-NLS-1$ - - Field[] fields = Issue.class.getDeclaredFields(); - for (Field field : fields) { + + final Field[] fields = Issue.class.getDeclaredFields(); + for (final Field field : fields) { if(field.isAnnotationPresent(IssuePropertyMapping.class)) { - IssuePropertyMapping annotation = (IssuePropertyMapping)field.getAnnotation(IssuePropertyMapping.class); - String key = annotation.value().getSubmitKey(); - String value = annotation.value().getSubmitValue(field, issue); + final IssuePropertyMapping annotation = field.getAnnotation(IssuePropertyMapping.class); + final String key = annotation.value().getSubmitKey(); + final String value = annotation.value().getSubmitValue(field, issue); writeValue(jsonWriter, key, value); } } - + if (issue.isWatchersAddAllowed() || issue.isWatchersDeleteAllowed() ) { jsonWriter.key("watcher_user_ids").array(); - for (int userId : issue.getWatcherIds()) { + for (final int userId : issue.getWatcherIds()) { jsonWriter.value(userId); } jsonWriter.endArray(); } writeCustomValues(jsonWriter, issue.getCustomValues()); - + jsonWriter.endObject(); } - - private static void writeIssueValues(JSONWriter jsonWriter, Map issue) throws JSONException { + + private static void writeIssueValues(final JSONWriter jsonWriter, final Map issue) throws JSONException { jsonWriter.key("issue").object(); //$NON-NLS-1$ - - for (Entry entry : issue.entrySet()) { + + for (final Entry entry : issue.entrySet()) { writeValue(jsonWriter, entry.getKey().getSubmitKey(), entry.getValue()); } - + jsonWriter.endObject(); } - - private static void writeCustomValues(JSONWriter jsonWriter, CustomValues values) throws JSONException { + + private static void writeCustomValues(final JSONWriter jsonWriter, final CustomValues values) throws JSONException { if(values!=null && values.getAll().size()>0) { jsonWriter.key("custom_field_values").object(); //$NON-NLS-1$ - - for (CustomValue customValue : values.getAll()) { + + for (final CustomValue customValue : values.getAll()) { writeValue(jsonWriter, ""+customValue.getCustomFieldId(), customValue.getValue()); //$NON-NLS-1$ } - + jsonWriter.endObject(); } } - - - private static void writeMappedValues(JSONWriter jsonWriter, Map values) throws JSONException { + + + private static void writeMappedValues(final JSONWriter jsonWriter, final Map values) throws JSONException { if(values!=null && values.size()>0) { - - for (Entry entry : values.entrySet()) { + + for (final Entry entry : values.entrySet()) { if(!entry.getKey().isEmpty()) { - + } writeValue(jsonWriter, entry.getKey(), entry.getValue()); } - + } } - - private static void writeValue(JSONWriter jsonWriter, String key, String value) throws JSONException { - jsonWriter.key(key).value(value==null ? "" : value); //$NON-NLS-1$ + + private static void writeValue(final JSONWriter jsonWriter, final String key, final String value) throws JSONException { + try { + final JSONArray array = new JSONArray(value); + jsonWriter.key(key).value(array); + } catch (final JSONException e) { + jsonWriter.key(key).value(value==null ? "" : value.replaceAll("\\n", "\r\n")); //$NON-NLS-1$ + } } - + } diff --git a/net.sf.redmine_mylyn.api/src/net/sf/redmine_mylyn/internal/api/messages.properties b/net.sf.redmine_mylyn.api/src/net/sf/redmine_mylyn/internal/api/messages.properties index 7c9b4b7..e7cb304 100644 --- a/net.sf.redmine_mylyn.api/src/net/sf/redmine_mylyn/internal/api/messages.properties +++ b/net.sf.redmine_mylyn.api/src/net/sf/redmine_mylyn/internal/api/messages.properties @@ -14,6 +14,7 @@ ERRMSG_INVALID_ENCODING_X=Invalid encoding {} ERRMSG_INVALID_REDMINE_URL=Repository URL doesn't point to a valid Redmine installation with Redmine plugin 2.7 or higher ERRMSG_METHOD_EXECUTION_FAILED=Execution of method failed ERRMSG_METHOD_EXECUTION_FAILED_INVALID_ENCODING=Execution of method failed - Invalid encoding {} +ERRMSG_METHOD_EXECUTION_FAILED_MIDAIR_CONFLICT=The issue was updated by another user on {0}. Please update local copy and retry. ERRMSG_METHOD_EXECUTION_FAILED_X=Execution of method failed - {0} ERRMSG_MISSING_CREDENTIALS_SYNCHRONIZATION_FAILED=Credentials not stored, manually syncronization required ERRMSG_PARAMETER_X_INVALID_INTEGER=Parameter `{0}` isn't a valid Integer value diff --git a/net.sf.redmine_mylyn.common/.settings/org.eclipse.jdt.core.prefs b/net.sf.redmine_mylyn.common/.settings/org.eclipse.jdt.core.prefs index 0ac5fbd..c537b63 100644 --- a/net.sf.redmine_mylyn.common/.settings/org.eclipse.jdt.core.prefs +++ b/net.sf.redmine_mylyn.common/.settings/org.eclipse.jdt.core.prefs @@ -1,4 +1,3 @@ -#Wed Sep 08 08:10:39 CEST 2010 eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 diff --git a/net.sf.redmine_mylyn.common/META-INF/MANIFEST.MF b/net.sf.redmine_mylyn.common/META-INF/MANIFEST.MF index ef780dc..c618945 100644 --- a/net.sf.redmine_mylyn.common/META-INF/MANIFEST.MF +++ b/net.sf.redmine_mylyn.common/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: net.sf.redmine_mylyn.common;singleton:=true -Bundle-Version: 0.4.0.qualifier +Bundle-Version: 0.4.1.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-Activator: net.sf.redmine_mylyn.common.RedmineCommonPlugin @@ -11,8 +11,7 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="3.5.0", org.slf4j.api;bundle-version="1.5.11", ch.qos.logback.classic;bundle-version="0.9.19", ch.qos.logback.core;bundle-version="0.9.19", - org.eclipse.osgi.services;bundle-version="3.2.0", - org.eclipse.equinox.log;bundle-version="1.2.0" + org.eclipse.osgi.services;bundle-version="3.2.0" Service-Component: OSGI-INF/logServiceComponent.xml, OSGI-INF/logWriterComponent.xml Bundle-ActivationPolicy: lazy Bundle-Localization: plugin diff --git a/net.sf.redmine_mylyn.common/pom.xml b/net.sf.redmine_mylyn.common/pom.xml index b3399fb..a600bc9 100644 --- a/net.sf.redmine_mylyn.common/pom.xml +++ b/net.sf.redmine_mylyn.common/pom.xml @@ -7,7 +7,7 @@ net.sf.redmine_mylyn net.sf.redmine_mylyn.parent - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT net.sf.redmine_mylyn.common diff --git a/net.sf.redmine_mylyn.common/src/net/sf/redmine_mylyn/common/RedmineCommonPlugin.java b/net.sf.redmine_mylyn.common/src/net/sf/redmine_mylyn/common/RedmineCommonPlugin.java index 1583b4c..71e56e8 100644 --- a/net.sf.redmine_mylyn.common/src/net/sf/redmine_mylyn/common/RedmineCommonPlugin.java +++ b/net.sf.redmine_mylyn.common/src/net/sf/redmine_mylyn/common/RedmineCommonPlugin.java @@ -9,28 +9,28 @@ public class RedmineCommonPlugin extends Plugin { public final static String PLUGIN_ID = "net.sf.redmine_mylyn.common.RedmineCommonPlugin"; //$NON-NLS-1$ - + private static RedmineCommonPlugin plugin; @Override - public void start(BundleContext context) throws Exception { + public void start(final BundleContext context) throws Exception { super.start(context); - + plugin = this; - Bundle logBundle = Platform.getBundle("org.eclipse.equinox.log"); //$NON-NLS-1$ - if (logBundle.getState()==Bundle.RESOLVED) { + final Bundle logBundle = Platform.getBundle("org.eclipse.equinox.log"); //$NON-NLS-1$ + if (logBundle != null && logBundle.getState()==Bundle.RESOLVED) { logBundle.start(); } } @Override - public void stop(BundleContext context) throws Exception { + public void stop(final BundleContext context) throws Exception { plugin = null; - + super.stop(context); } - + public static RedmineCommonPlugin getDefault() { return plugin; } diff --git a/net.sf.redmine_mylyn.core/.settings/org.eclipse.jdt.core.prefs b/net.sf.redmine_mylyn.core/.settings/org.eclipse.jdt.core.prefs index 4d4e4c3..8000cd6 100644 --- a/net.sf.redmine_mylyn.core/.settings/org.eclipse.jdt.core.prefs +++ b/net.sf.redmine_mylyn.core/.settings/org.eclipse.jdt.core.prefs @@ -1,4 +1,3 @@ -#Tue Sep 14 21:44:22 CEST 2010 eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 diff --git a/net.sf.redmine_mylyn.core/META-INF/MANIFEST.MF b/net.sf.redmine_mylyn.core/META-INF/MANIFEST.MF index c3e0c34..990280a 100644 --- a/net.sf.redmine_mylyn.core/META-INF/MANIFEST.MF +++ b/net.sf.redmine_mylyn.core/META-INF/MANIFEST.MF @@ -2,16 +2,16 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: net.sf.redmine_mylyn.core;singleton:=true -Bundle-Version: 0.4.0.qualifier +Bundle-Version: 0.4.1.qualifier Bundle-Activator: net.sf.redmine_mylyn.core.RedmineCorePlugin Bundle-Vendor: %Bundle-Vendor Require-Bundle: org.eclipse.core.runtime;bundle-version="3.5.0", org.eclipse.mylyn.tasks.core;bundle-version="3.5.0", org.eclipse.mylyn.commons.core;bundle-version="3.5.0", org.eclipse.mylyn.commons.net;bundle-version="3.5.0", - net.sf.redmine_mylyn.common;bundle-version="0.4.0", - net.sf.redmine_mylyn.api;bundle-version="0.4.0", - org.aspectj.runtime;bundle-version="1.6.0" + net.sf.redmine_mylyn.common;bundle-version="0.4.1", + net.sf.redmine_mylyn.api;bundle-version="0.4.1", + org.aspectj.runtime;bundle-version="1.7.0" Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-ActivationPolicy: lazy Export-Package: net.sf.redmine_mylyn.core, diff --git a/net.sf.redmine_mylyn.core/pom.xml b/net.sf.redmine_mylyn.core/pom.xml index 4df7c15..d7b825e 100644 --- a/net.sf.redmine_mylyn.core/pom.xml +++ b/net.sf.redmine_mylyn.core/pom.xml @@ -7,7 +7,7 @@ net.sf.redmine_mylyn net.sf.redmine_mylyn.parent - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT net.sf.redmine_mylyn.core diff --git a/net.sf.redmine_mylyn.core/src/net/sf/redmine_mylyn/core/RedmineTaskAttributeMapper.java b/net.sf.redmine_mylyn.core/src/net/sf/redmine_mylyn/core/RedmineTaskAttributeMapper.java index fb90462..df13364 100644 --- a/net.sf.redmine_mylyn.core/src/net/sf/redmine_mylyn/core/RedmineTaskAttributeMapper.java +++ b/net.sf.redmine_mylyn.core/src/net/sf/redmine_mylyn/core/RedmineTaskAttributeMapper.java @@ -10,24 +10,24 @@ public class RedmineTaskAttributeMapper extends TaskAttributeMapper { - private Configuration configuration; - - public RedmineTaskAttributeMapper(TaskRepository taskRepository, Configuration configuration) { + private final Configuration configuration; + + public RedmineTaskAttributeMapper(final TaskRepository taskRepository, final Configuration configuration) { super(taskRepository); this.configuration = configuration; } - + @Override - public void setRepositoryPerson(TaskAttribute taskAttribute, IRepositoryPerson person) { + public void setRepositoryPerson(final TaskAttribute taskAttribute, final IRepositoryPerson person) { User user = null; - + if (person.getPersonId()!=null && !person.getPersonId().isEmpty()) { user = configuration.getUsers().getByLogin(person.getPersonId()); if (user==null && person.getPersonId().matches(IRedmineConstants.REGEX_INTEGER)) { user = configuration.getUsers().getById(RedmineUtil.parseIntegerId(person.getPersonId())); } } - + if(user!=null) { setValue(taskAttribute, ""+ user.getId()); //$NON-NLS-1$ } else { @@ -36,26 +36,33 @@ public void setRepositoryPerson(TaskAttribute taskAttribute, IRepositoryPerson p } @Override - public IRepositoryPerson getRepositoryPerson(TaskAttribute taskAttribute) { + public IRepositoryPerson getRepositoryPerson(final TaskAttribute taskAttribute) { User user = null; - + if (!taskAttribute.getValue().isEmpty()) { if(RedmineUtil.isInteger(taskAttribute.getValue())) { user = configuration.getUsers().getById(RedmineUtil.parseIntegerId(taskAttribute.getValue())); } - + if (user==null) { user = configuration.getUsers().getByLogin(taskAttribute.getValue()); } - + if (user!=null) { - IRepositoryPerson person = getTaskRepository().createPerson(user.getLogin()); + final String login = user.getLogin(); + final String id; + if (login.isEmpty()) { + id = user.getName(); + } else { + id = login; + } + final IRepositoryPerson person = getTaskRepository().createPerson(id); person.setName(user.getName()); return person; } } - - IRepositoryPerson person = super.getRepositoryPerson(taskAttribute); + + final IRepositoryPerson person = super.getRepositoryPerson(taskAttribute); if (person.getName()==null) { person.setName(""); //$NON-NLS-1$ } @@ -63,28 +70,28 @@ public IRepositoryPerson getRepositoryPerson(TaskAttribute taskAttribute) { } @Override - public boolean getBooleanValue(TaskAttribute attribute) { - String value = attribute.getValue(); + public boolean getBooleanValue(final TaskAttribute attribute) { + final String value = attribute.getValue(); if (value.equals(IRedmineConstants.BOOLEAN_TRUE_SUBMIT_VALUE)) { return true; } return super.getBooleanValue(attribute); } - -@Override -public void setValue(TaskAttribute attribute, String value) { - - if (attribute.getMetaData().getKind()!=null && attribute.getMetaData().getKind().equals(TaskAttribute.KIND_PEOPLE)) { - if (!value.isEmpty() && !value.matches(IRedmineConstants.REGEX_INTEGER)) { - User user = configuration.getUsers().getByLogin(value); - if(user!=null) { - super.setValue(attribute, ""+user.getId()); //$NON-NLS-N$ - return; + + @Override + public void setValue(final TaskAttribute attribute, final String value) { + + if (attribute.getMetaData().getKind()!=null && attribute.getMetaData().getKind().equals(TaskAttribute.KIND_PEOPLE)) { + if (!value.isEmpty() && !value.matches(IRedmineConstants.REGEX_INTEGER)) { + final User user = configuration.getUsers().getByLogin(value); + if(user!=null) { + super.setValue(attribute, ""+user.getId()); + return; + } } } + + super.setValue(attribute, value); } - - super.setValue(attribute, value); -} - + } diff --git a/net.sf.redmine_mylyn.core/src/net/sf/redmine_mylyn/core/RedmineTaskDataHandler.java b/net.sf.redmine_mylyn.core/src/net/sf/redmine_mylyn/core/RedmineTaskDataHandler.java index ee943a5..348c204 100644 --- a/net.sf.redmine_mylyn.core/src/net/sf/redmine_mylyn/core/RedmineTaskDataHandler.java +++ b/net.sf.redmine_mylyn.core/src/net/sf/redmine_mylyn/core/RedmineTaskDataHandler.java @@ -1,5 +1,6 @@ package net.sf.redmine_mylyn.core; +import java.util.Date; import java.util.List; import java.util.Map.Entry; import java.util.Set; @@ -40,96 +41,96 @@ public class RedmineTaskDataHandler extends AbstractTaskDataHandler { - private RedmineRepositoryConnector connector; - - public RedmineTaskDataHandler(RedmineRepositoryConnector connector) { + private final RedmineRepositoryConnector connector; + + public RedmineTaskDataHandler(final RedmineRepositoryConnector connector) { this.connector = connector; } @Override - public boolean canGetMultiTaskData(TaskRepository taskRepository) { + public boolean canGetMultiTaskData(final TaskRepository taskRepository) { return true; } @Override - public void getMultiTaskData(TaskRepository repository, Set taskIds, TaskDataCollector collector, IProgressMonitor monitor) throws CoreException { - TaskData[] taskData = connector.getTaskData(repository, taskIds, monitor); - for (TaskData data : taskData) { + public void getMultiTaskData(final TaskRepository repository, final Set taskIds, final TaskDataCollector collector, final IProgressMonitor monitor) throws CoreException { + final TaskData[] taskData = connector.getTaskData(repository, taskIds, monitor); + for (final TaskData data : taskData) { if (data!=null) { collector.accept(data); } } } - + @Override - public boolean canInitializeSubTaskData(TaskRepository taskRepository, ITask task) { + public boolean canInitializeSubTaskData(final TaskRepository taskRepository, final ITask task) { return true; } - + @Override - public TaskAttributeMapper getAttributeMapper(TaskRepository repository) { + public TaskAttributeMapper getAttributeMapper(final TaskRepository repository) { return new RedmineTaskAttributeMapper(repository, connector.getRepositoryConfiguration(repository)); } - + @Override - public boolean initializeSubTaskData(TaskRepository repository, TaskData taskData, TaskData parentTaskData, IProgressMonitor monitor) throws CoreException { - Issue issue = new Issue(); - - TaskAttribute parentRoot = parentTaskData.getRoot(); + public boolean initializeSubTaskData(final TaskRepository repository, final TaskData taskData, final TaskData parentTaskData, final IProgressMonitor monitor) throws CoreException { + final Issue issue = new Issue(); + + final TaskAttribute parentRoot = parentTaskData.getRoot(); issue.setProjectId(RedmineUtil.parseIntegerId(parentRoot.getAttribute(RedmineAttribute.PROJECT.getTaskKey()).getValue())); issue.setTrackerId(RedmineUtil.parseIntegerId(parentRoot.getAttribute(RedmineAttribute.TRACKER.getTaskKey()).getValue())); - - + + if(initializeNewTaskData(issue, repository, taskData, monitor)) { - TaskAttribute childRoot = taskData.getRoot(); + final TaskAttribute childRoot = taskData.getRoot(); childRoot.getAttribute(RedmineAttribute.PARENT.getTaskKey()).setValue(parentTaskData.getTaskId()); childRoot.getAttribute(RedmineAttribute.CATEGORY.getTaskKey()).setValue(parentRoot.getAttribute(RedmineAttribute.CATEGORY.getTaskKey()).getValue()); childRoot.getAttribute(RedmineAttribute.VERSION.getTaskKey()).setValue(parentRoot.getAttribute(RedmineAttribute.VERSION.getTaskKey()).getValue()); childRoot.getAttribute(RedmineAttribute.PRIORITY.getTaskKey()).setValue(parentRoot.getAttribute(RedmineAttribute.PRIORITY.getTaskKey()).getValue()); - + return true; } return false; } @Override - public boolean initializeTaskData(TaskRepository repository, TaskData taskData, ITaskMapping taskMapping, IProgressMonitor monitor) throws CoreException { - Configuration conf = connector.getRepositoryConfiguration(repository); - Issue issue = new Issue(); - + public boolean initializeTaskData(final TaskRepository repository, final TaskData taskData, final ITaskMapping taskMapping, final IProgressMonitor monitor) throws CoreException { + final Configuration conf = connector.getRepositoryConfiguration(repository); + final Issue issue = new Issue(); + try { - Project project = conf.getProjects().getAll().get(0); + final Project project = conf.getProjects().getAll().get(0); issue.setProjectId(project.getId()); issue.setTrackerId(conf.getTrackers().getById(project.getTrackerIds()).get(0).getId()); - + return initializeNewTaskData(issue, repository, taskData, monitor); - } catch (RuntimeException e) { - IStatus status = new Status(IStatus.ERROR, RedmineCorePlugin.PLUGIN_ID, Messages.ERRMSG_TASK_INITIALIZATION_FALED_INSUFFICENT_DATA, e); + } catch (final RuntimeException e) { + final IStatus status = new Status(IStatus.ERROR, RedmineCorePlugin.PLUGIN_ID, Messages.ERRMSG_TASK_INITIALIZATION_FALED_INSUFFICENT_DATA, e); StatusHandler.log(status); throw new CoreException(status); } } - private boolean initializeNewTaskData(Issue issue, TaskRepository repository, TaskData taskData, IProgressMonitor monitor) throws CoreException { - Configuration conf = connector.getRepositoryConfiguration(repository); - + private boolean initializeNewTaskData(final Issue issue, final TaskRepository repository, final TaskData taskData, final IProgressMonitor monitor) throws CoreException { + final Configuration conf = connector.getRepositoryConfiguration(repository); + try { createAttributes(repository, taskData, issue, conf); createOperations(taskData, issue, conf); - + /* Default-Values */ - TaskAttribute root = taskData.getRoot(); + final TaskAttribute root = taskData.getRoot(); root.getAttribute(RedmineAttribute.PROJECT.getTaskKey()).setValue(""+issue.getProjectId()); //$NON-NLS-1$ root.getAttribute(RedmineAttribute.TRACKER.getTaskKey()).setValue(""+issue.getTrackerId()); //$NON-NLS-1$ - - IssuePriority priority = conf.getIssuePriorities().getDefault(); + + final IssuePriority priority = conf.getIssuePriorities().getDefault(); if(priority!=null) { root.getAttribute(RedmineAttribute.PRIORITY.getTaskKey()).setValue(""+priority.getId()); //$NON-NLS-1$ } else if(conf.getIssuePriorities().getAll().size()>0){ root.getAttribute(RedmineAttribute.PRIORITY.getTaskKey()).setValue(""+conf.getIssuePriorities().getAll().get(0)); //$NON-NLS-1$ } - - IssueStatus status = conf.getIssueStatuses().getDefault(); + + final IssueStatus status = conf.getIssueStatuses().getDefault(); if(status!=null) { root.getAttribute(RedmineAttribute.STATUS.getTaskKey()).setValue(""+status.getId()); //$NON-NLS-1$ root.getAttribute(RedmineAttribute.STATUS_CHG.getTaskKey()).setValue(""+status.getId()); //$NON-NLS-1$ @@ -137,90 +138,92 @@ private boolean initializeNewTaskData(Issue issue, TaskRepository repository, Ta root.getAttribute(RedmineAttribute.STATUS.getTaskKey()).setValue(""+conf.getIssueStatuses().getAll().get(0)); //$NON-NLS-1$ root.getAttribute(RedmineAttribute.STATUS_CHG.getTaskKey()).setValue(""+conf.getIssueStatuses().getAll().get(0)); //$NON-NLS-1$ } - - } catch (RedmineStatusException e) { + + } catch (final RedmineStatusException e) { throw new CoreException(RedmineCorePlugin.toStatus(e, e.getMessage())); } - + return true; } - + @Override - public RepositoryResponse postTaskData(TaskRepository repository, TaskData taskData, Set oldAttributes, IProgressMonitor monitor) throws CoreException { + public RepositoryResponse postTaskData(final TaskRepository repository, final TaskData taskData, final Set oldAttributes, final IProgressMonitor monitor) throws CoreException { String taskId = taskData.getTaskId(); try { - IClient client = connector.getClientManager().getClient(repository); - Configuration cfg = connector.getRepositoryConfiguration(repository); + final IClient client = connector.getClientManager().getClient(repository); + final Configuration cfg = connector.getRepositoryConfiguration(repository); if(taskData.isNew() || taskId.isEmpty()) { - Issue issue = IssueMapper.createIssue(repository, taskData, oldAttributes, cfg); + final Issue issue = IssueMapper.createIssue(repository, taskData, oldAttributes, cfg); taskId += client.createIssue(issue, monitor); } else { - Issue issue = IssueMapper.createIssue(repository, taskData, oldAttributes, cfg); - TimeEntry timeEntry = IssueMapper.createTimeEntry(repository, taskData, oldAttributes, cfg); - TaskAttribute commentAttribute = taskData.getRoot().getAttribute(RedmineAttribute.COMMENT.getTaskKey()); - String comment = commentAttribute==null ? null : commentAttribute.getValue(); - client.updateIssue(issue, comment, timeEntry, monitor); + final Issue issue = IssueMapper.createIssue(repository, taskData, oldAttributes, cfg); + final TimeEntry timeEntry = IssueMapper.createTimeEntry(repository, taskData, oldAttributes, cfg); + final TaskAttribute commentAttribute = taskData.getRoot().getAttribute(RedmineAttribute.COMMENT.getTaskKey()); + final String comment = commentAttribute==null ? null : commentAttribute.getValue(); + final TaskAttribute attribute = taskData.getRoot().getAttribute(RedmineAttribute.DATE_UPDATED.getTaskKey()); + final Date lastModified = RedmineUtil.parseDate(attribute.getValue()); + client.updateIssue(issue, comment, lastModified, timeEntry, monitor); } - } catch (RedmineStatusException e) { + } catch (final RedmineStatusException e) { throw new CoreException(e.getStatus()); } - + return new RepositoryResponse(ResponseKind.TASK_CREATED, "" + taskId); //$NON-NLS-1$ } - - public TaskData createTaskDataFromIssue(TaskRepository repository, Issue issue, IProgressMonitor monitor) throws CoreException { - Configuration configuration = connector.getRepositoryConfiguration(repository); + public TaskData createTaskDataFromIssue(final TaskRepository repository, final Issue issue, final IProgressMonitor monitor) throws CoreException { + + final Configuration configuration = connector.getRepositoryConfiguration(repository); try { - TaskData taskData = new TaskData(getAttributeMapper(repository), RedmineCorePlugin.REPOSITORY_KIND, repository.getRepositoryUrl(), issue.getId() + ""); //$NON-NLS-1$ + final TaskData taskData = new TaskData(getAttributeMapper(repository), RedmineCorePlugin.REPOSITORY_KIND, repository.getRepositoryUrl(), issue.getId() + ""); //$NON-NLS-1$ createAttributes(repository, taskData, issue, configuration); createOperations(taskData, issue, configuration); IssueMapper.updateTaskData(repository, taskData, configuration, issue); return taskData; - } catch (RedmineStatusException e) { - IStatus status = RedmineCorePlugin.toStatus(e, e.getMessage()); + } catch (final RedmineStatusException e) { + final IStatus status = RedmineCorePlugin.toStatus(e, e.getMessage()); throw new CoreException(status); } } - private void createAttributes(TaskRepository repository, TaskData data, Issue issue, Configuration configuration) throws RedmineStatusException { + private void createAttributes(final TaskRepository repository, final TaskData data, final Issue issue, final Configuration configuration) throws RedmineStatusException { createDefaultAttributes(repository, data, issue, configuration); createCustomAttributes(data, configuration, issue, configuration.getCustomFields().getIssueCustomFields(), IRedmineConstants.TASK_KEY_PREFIX_ISSUE_CF, false); } - - private static void createDefaultAttributes(TaskRepository repository, TaskData data, Issue issue , Configuration cfg) throws RedmineStatusException { - boolean existingTask = issue.getId()>0; - Project project = cfg.getProjects().getById(issue.getProjectId()); + + private static void createDefaultAttributes(final TaskRepository repository, final TaskData data, final Issue issue , final Configuration cfg) throws RedmineStatusException { + final boolean existingTask = issue.getId()>0; + final Project project = cfg.getProjects().getById(issue.getProjectId()); if (project==null) { //https://sourceforge.net/tracker/index.php?func=detail&aid=3441198&group_id=228995&atid=1075435# - IStatus status = RedmineCorePlugin.toStatus(IStatus.ERROR, Messages.ERRMSG_TASK_INITIALIZATION_FALED_INSUFFICENT_DATA_X_X, issue.getId(), "Project" + " " + issue.getProjectId() ); + final IStatus status = RedmineCorePlugin.toStatus(IStatus.ERROR, Messages.ERRMSG_TASK_INITIALIZATION_FALED_INSUFFICENT_DATA_X_X, issue.getId(), "Project" + " " + issue.getProjectId() ); StatusHandler.log(status); throw new RedmineStatusException(status); } if (cfg.getSettings()==null) { //https://sourceforge.net/tracker/index.php?func=detail&aid=3441198&group_id=228995&atid=1075435# - IStatus status = RedmineCorePlugin.toStatus(IStatus.ERROR, Messages.ERRMSG_TASK_INITIALIZATION_FALED_INSUFFICENT_DATA_X_X, issue.getId(), "Settings" ); + final IStatus status = RedmineCorePlugin.toStatus(IStatus.ERROR, Messages.ERRMSG_TASK_INITIALIZATION_FALED_INSUFFICENT_DATA_X_X, issue.getId(), "Settings" ); StatusHandler.log(status); throw new RedmineStatusException(status); } TaskAttribute attribute; - + createAttribute(data, RedmineAttribute.SUMMARY); createAttribute(data, RedmineAttribute.DESCRIPTION); createAttribute(data, RedmineAttribute.PRIORITY, cfg.getIssuePriorities().getAll()); - + if(existingTask) { attribute = createAttribute(data, RedmineAttribute.PROJECT, cfg.getProjects().getMoveAllowed(project)); attribute.getMetaData().setReadOnly(true); } else { createAttribute(data, RedmineAttribute.PROJECT, cfg.getProjects().getNewAllowed()); } - + createAttribute(data, RedmineAttribute.PARENT); createAttribute(data, RedmineAttribute.SUBTASKS); createAttribute(data, RedmineAttribute.TRACKER, cfg.getTrackers().getById(project.getTrackerIds())); @@ -229,29 +232,29 @@ private static void createDefaultAttributes(TaskRepository repository, TaskData createAttribute(data, RedmineAttribute.REPORTER); createAttribute(data, RedmineAttribute.DATE_SUBMITTED); createAttribute(data, RedmineAttribute.DATE_UPDATED); - + createAttribute(data, RedmineAttribute.COMMENT); - + createAttribute(data, RedmineAttribute.STATUS, cfg.getIssueStatuses().getById(issue.getAvailableStatusId())); createAttribute(data, RedmineAttribute.STATUS_CHG, cfg.getIssueStatuses().getById(issue.getAvailableStatusId())); -//// createAttribute(data, RedmineAttribute.RELATION, ticket.getRelations(), false); -// + //// createAttribute(data, RedmineAttribute.RELATION, ticket.getRelations(), false); + // } else { createAttribute(data, RedmineAttribute.STATUS, cfg.getIssueStatuses().getAll()); createAttribute(data, RedmineAttribute.STATUS_CHG, cfg.getIssueStatuses().getAll()); } - + createAttribute(data, RedmineAttribute.CATEGORY, cfg.getIssueCategories().getById(project.getIssueCategoryIds()), true); createAttribute(data, RedmineAttribute.VERSION, cfg.getVersions().getOpenById(project.getVersionIds()), true); - + attribute = createAttribute(data, RedmineAttribute.PROGRESS, ProgressValues.availableValues()); if (!cfg.getSettings().isUseIssueDoneRatio()) { attribute.getMetaData().setReadOnly(true); attribute.getMetaData().setType(null); } - + //Planning createAttribute(data, RedmineAttribute.ESTIMATED); createAttribute(data, RedmineAttribute.DATE_DUE); @@ -265,11 +268,11 @@ private static void createDefaultAttributes(TaskRepository repository, TaskData createAttribute(data, RedmineAttribute.TIME_ENTRY_HOURS); createAttribute(data, RedmineAttribute.TIME_ENTRY_ACTIVITY, project.getTimeEntryActivities().getAll()); createAttribute(data, RedmineAttribute.TIME_ENTRY_COMMENTS); - - for (IRedmineExtensionField additionalField : RedmineCorePlugin.getDefault().getExtensionManager().getAdditionalTimeEntryFields(repository)) { + + for (final IRedmineExtensionField additionalField : RedmineCorePlugin.getDefault().getExtensionManager().getAdditionalTimeEntryFields(repository)) { createAttribute(data, additionalField, IRedmineConstants.TASK_KEY_PREFIX_TIMEENTRY_EX); } - + createCustomAttributes(data, cfg, issue, cfg.getCustomFields().getTimeEntryCustomFields(), IRedmineConstants.TASK_KEY_PREFIX_TIMEENTRY_CF, true); } } @@ -278,9 +281,9 @@ private static void createDefaultAttributes(TaskRepository repository, TaskData if(existingTask) { if(issue.isWatchersViewAllowed()) { attribute = createAttribute(data, RedmineAttribute.WATCHERS, cfg.getUsers().getAll()); - + if(issue.isWatchersAddAllowed()) { - TaskAttribute addWatcherAttribute = attribute.createAttribute(RedmineAttribute.WATCHERS_ADD.getTaskKey()); + final TaskAttribute addWatcherAttribute = attribute.createAttribute(RedmineAttribute.WATCHERS_ADD.getTaskKey()); addWatcherAttribute.getMetaData().setLabel(RedmineAttribute.WATCHERS_ADD.getLabel()); addOptions(addWatcherAttribute, cfg.getUsers().getById(project.getMemberIds())); } @@ -291,22 +294,22 @@ private static void createDefaultAttributes(TaskRepository repository, TaskData } } } - - private static TaskAttribute createAttribute(TaskData data, RedmineAttribute redmineAttribute) { - TaskAttribute attr = data.getRoot().createAttribute(redmineAttribute.getTaskKey()); + + private static TaskAttribute createAttribute(final TaskData data, final RedmineAttribute redmineAttribute) { + final TaskAttribute attr = data.getRoot().createAttribute(redmineAttribute.getTaskKey()); attr.getMetaData().setType(redmineAttribute.getType()); attr.getMetaData().setKind(redmineAttribute.getKind()); attr.getMetaData().setLabel(redmineAttribute.toString()); attr.getMetaData().setReadOnly(redmineAttribute.isReadOnly()); return attr; } - - private static TaskAttribute createAttribute(TaskData data, RedmineAttribute redmineAttribute, List values) { + + private static TaskAttribute createAttribute(final TaskData data, final RedmineAttribute redmineAttribute, final List values) { return createAttribute(data, redmineAttribute, values, false); } - private static TaskAttribute createAttribute(TaskData data, RedmineAttribute redmineAttribute, List properties, boolean allowEmtpy) { - TaskAttribute attr = createAttribute(data, redmineAttribute); + private static TaskAttribute createAttribute(final TaskData data, final RedmineAttribute redmineAttribute, final List properties, final boolean allowEmtpy) { + final TaskAttribute attr = createAttribute(data, redmineAttribute); if (properties != null && properties.size() > 0) { if (allowEmtpy) { @@ -316,19 +319,19 @@ private static TaskAttribute createAttribute(TaskData data, RedmineAttribute red } return attr; } - - private static TaskAttribute addOptions(TaskAttribute attribute, List properties) { - for (Property property : properties) { + + private static TaskAttribute addOptions(final TaskAttribute attribute, final List properties) { + for (final Property property : properties) { attribute.putOption(String.valueOf(property.getId()), property.getName()); } return attribute; } - private static void createCustomAttributes(TaskData taskData, Configuration configuration, Issue issue , List customFields, String prefix, boolean hidden) throws RedmineStatusException { - Project project = configuration.getProjects().getById(issue.getProjectId()); - - for (CustomField customField : customFields) { - TaskAttribute taskAttribute = createAttribute(taskData, customField, prefix); + private static void createCustomAttributes(final TaskData taskData, final Configuration configuration, final Issue issue , final List customFields, final String prefix, final boolean hidden) throws RedmineStatusException { + final Project project = configuration.getProjects().getById(issue.getProjectId()); + + for (final CustomField customField : customFields) { + final TaskAttribute taskAttribute = createAttribute(taskData, customField, prefix); if(hidden) { taskAttribute.getMetaData().setKind(null); } @@ -336,81 +339,81 @@ private static void createCustomAttributes(TaskData taskData, Configuration conf if (!customField.isRequired()) { taskAttribute.putOption("", ""); //$NON-NLS-1$ //$NON-NLS-2$ } - + switch (customField.getFieldFormat()) { case VERSION: - for( Version version : configuration.getVersions().getById(project.getVersionIds()) ) { + for( final Version version : configuration.getVersions().getById(project.getVersionIds()) ) { taskAttribute.putOption(""+version.getId(), version.getName()); //$NON-NLS-1$ } break; - case USER: - for( Member member : project.getMembers() ) { - User user = configuration.getUsers().getById(member.getUserId()); + case USER: + for( final Member member : project.getMembers() ) { + final User user = configuration.getUsers().getById(member.getUserId()); if (user != null) { taskAttribute.putOption(""+user.getId(), user.getName()); //$NON-NLS-1$ } } break; default: - for (String option : customField.getPossibleValues()) { + for (final String option : customField.getPossibleValues()) { taskAttribute.putOption(option, option); } - } + } } - + } } - private static TaskAttribute createAttribute(TaskData taskData, CustomField customField, String prefix) { - TaskAttribute attr = taskData.getRoot().createAttribute(prefix + customField.getId()); + private static TaskAttribute createAttribute(final TaskData taskData, final CustomField customField, final String prefix) { + final TaskAttribute attr = taskData.getRoot().createAttribute(prefix + customField.getId()); attr.getMetaData().setType(RedmineUtil.getTaskAttributeType(customField)); attr.getMetaData().setKind(TaskAttribute.KIND_DEFAULT); attr.getMetaData().setLabel(customField.getName()); attr.getMetaData().setReadOnly(false); return attr; } - - private static TaskAttribute createAttribute(TaskData taskData, IRedmineExtensionField additionalField, String prefix) { - TaskAttribute attr = taskData.getRoot().createAttribute(prefix + additionalField.getTaskKey()); + + private static TaskAttribute createAttribute(final TaskData taskData, final IRedmineExtensionField additionalField, final String prefix) { + final TaskAttribute attr = taskData.getRoot().createAttribute(prefix + additionalField.getTaskKey()); attr.getMetaData().setType(additionalField.getEditorType()); attr.getMetaData().setLabel(additionalField.getLabel()); attr.getMetaData().setReadOnly(false); - + if (additionalField.getOptions()!=null) { if (!additionalField.isRequired()) { attr.putOption("", ""); //$NON-NLS-1$ //$NON-NLS-2$ } - for (Entry entry : additionalField.getOptions().entrySet()) { + for (final Entry entry : additionalField.getOptions().entrySet()) { attr.putOption(entry.getKey(), entry.getValue()); } - + } return attr; } - - private void createOperations(TaskData taskData, Issue issue, Configuration configuration) { + + private void createOperations(final TaskData taskData, final Issue issue, final Configuration configuration) { IssueStatus currentStatus = null; if(issue!=null) { currentStatus = configuration.getIssueStatuses().getById(issue.getStatusId()); } - + if(currentStatus!=null) { createOperation(taskData, RedmineOperation.none, ""+currentStatus.getId(), currentStatus.getName()); //$NON-NLS-1$ } - + createOperation(taskData, RedmineOperation.markas, null); } - private static TaskAttribute createOperation(TaskData taskData, RedmineOperation operation, String defaultValue, Object... labelArgs) { + private static TaskAttribute createOperation(final TaskData taskData, final RedmineOperation operation, final String defaultValue, final Object... labelArgs) { TaskAttribute operationAttrib = taskData.getRoot().getAttribute(TaskAttribute.OPERATION); if(operationAttrib==null) { operationAttrib = taskData.getRoot().createAttribute(TaskAttribute.OPERATION); TaskOperation.applyTo(operationAttrib, operation.toString(), null); } - TaskAttribute attribute = taskData.getRoot().createAttribute(TaskAttribute.PREFIX_OPERATION + operation.getTaskKey()); + final TaskAttribute attribute = taskData.getRoot().createAttribute(TaskAttribute.PREFIX_OPERATION + operation.getTaskKey()); TaskOperation.applyTo(attribute, operation.getTaskKey(), operation.getLabel(labelArgs)); - + if(operation.isAssociated()) { attribute.getMetaData().putValue(TaskAttribute.META_ASSOCIATED_ATTRIBUTE_ID, operation.getInputId()); } else if(operation.needsRestoreValue() && defaultValue!=null && defaultValue!=""){ //$NON-NLS-1$ diff --git a/net.sf.redmine_mylyn.core/src/net/sf/redmine_mylyn/core/RedmineUtil.java b/net.sf.redmine_mylyn.core/src/net/sf/redmine_mylyn/core/RedmineUtil.java index ddb1416..61d0216 100644 --- a/net.sf.redmine_mylyn.core/src/net/sf/redmine_mylyn/core/RedmineUtil.java +++ b/net.sf.redmine_mylyn.core/src/net/sf/redmine_mylyn/core/RedmineUtil.java @@ -13,60 +13,60 @@ import org.eclipse.mylyn.tasks.core.data.TaskAttribute; public class RedmineUtil { - + private final static SimpleDateFormat df = new SimpleDateFormat(IRedmineConstants.DATE_FORMAT); - - public static boolean isInteger(String val) { + + public static boolean isInteger(final String val) { return val.matches(IRedmineConstants.REGEX_INTEGER); } - - public static int parseIntegerId(String intVal) { + + public static int parseIntegerId(final String intVal) { if(intVal!=null && !intVal.isEmpty()) { try { return Integer.parseInt(intVal); - } catch(NumberFormatException e) { - IStatus status = RedmineCorePlugin.toStatus(e, Messages.ERRMSG_X_VALID_INTEGER, intVal); + } catch(final NumberFormatException e) { + final IStatus status = RedmineCorePlugin.toStatus(e, Messages.ERRMSG_X_VALID_INTEGER, intVal); StatusHandler.log(status); } } return 0; - } + } - public static Boolean parseBoolean(String value) { + public static Boolean parseBoolean(final String value) { return value!=null && value.trim().equals(IRedmineConstants.BOOLEAN_TRUE_SUBMIT_VALUE) ? Boolean.TRUE : Boolean.parseBoolean(value); } - - public static String formatDate(Date date) { + + public static String formatDate(final Date date) { if(date!=null) { return df.format(date); } return null; } - - public static Date parseDate(String value) { + + public static Date parseDate(final String value) { if(value!=null && !value.isEmpty()) { try { //try timestamp return new Date(Long.parseLong(value)); - } catch(NumberFormatException e) { + } catch(final NumberFormatException e) { ;//nothing to do } } return new Date(0); } - public static Date parseRedmineDate(String value) { + public static Date parseRedmineDate(final String value) { if(value!=null && !value.isEmpty()) { try { //try timestamp - long timestamp = Long.parseLong(value); + final long timestamp = Long.parseLong(value); return new Date(timestamp*1000); - } catch(NumberFormatException e) { + } catch(final NumberFormatException e) { try { //try formated date return df.parse(value); - } catch (ParseException e1) { - IStatus status = RedmineCorePlugin.toStatus(e, Messages.ERRMSG_X_VALID_UNIXTIME_DATE, value); + } catch (final ParseException e1) { + final IStatus status = RedmineCorePlugin.toStatus(e, Messages.ERRMSG_X_VALID_UNIXTIME_DATE, value); StatusHandler.log(status); } } @@ -74,7 +74,7 @@ public static Date parseRedmineDate(String value) { return null; } - public static String getTaskAttributeType(CustomField customField) { + public static String getTaskAttributeType(final CustomField customField) { String type = TaskAttribute.TYPE_SHORT_TEXT; switch (customField.getFieldFormat()) { case TEXT: @@ -82,7 +82,11 @@ public static String getTaskAttributeType(CustomField customField) { break; case LIST: case VERSION: - type = TaskAttribute.TYPE_SINGLE_SELECT; + if (customField.isMultiple()) { + type = TaskAttribute.TYPE_MULTI_SELECT; + } else { + type = TaskAttribute.TYPE_SINGLE_SELECT; + } break; case DATE: type = TaskAttribute.TYPE_DATE; @@ -99,27 +103,27 @@ public static String getTaskAttributeType(CustomField customField) { return type; } - public static String formatUserPresentation (IRepositoryPerson person) { + public static String formatUserPresentation (final IRepositoryPerson person) { return formatUserPresentation(person.getPersonId(), person.getName()); } - - public static String formatUserPresentation (String login, String name) { + + public static String formatUserPresentation (final String login, final String name) { if (login!=null && !login.isEmpty() && !login.equals("0") ) { //$NON-NLS-1$ return name + " <" + login + ">"; //$NON-NLS-1$ //$NON-NLS-2$ - + } return name; } - - public static String findUserLogin(String userPresentation) { + + public static String findUserLogin(final String userPresentation) { if (userPresentation!=null && !userPresentation.isEmpty()) { - int ltr = userPresentation.lastIndexOf('<'); - int rtr = userPresentation.lastIndexOf('>'); - + final int ltr = userPresentation.lastIndexOf('<'); + final int rtr = userPresentation.lastIndexOf('>'); + if (ltr>-1 && rtr>ltr+1) { return userPresentation.substring(ltr+1, rtr); } - + } return null; } diff --git a/net.sf.redmine_mylyn.core/src/net/sf/redmine_mylyn/core/client/IClient.java b/net.sf.redmine_mylyn.core/src/net/sf/redmine_mylyn/core/client/IClient.java index 8304aba..6d383d0 100644 --- a/net.sf.redmine_mylyn.core/src/net/sf/redmine_mylyn/core/client/IClient.java +++ b/net.sf.redmine_mylyn.core/src/net/sf/redmine_mylyn/core/client/IClient.java @@ -22,25 +22,25 @@ public interface IClient { public Configuration getConfiguration(); public void updateConfiguration(IProgressMonitor monitor) throws RedmineStatusException; - + public RedmineServerVersion checkClientConnection(IProgressMonitor monitor) throws RedmineStatusException; - + public Issue getIssue(int id, IProgressMonitor monitor) throws RedmineStatusException; - + public Issue[] getIssues(Set ids, IProgressMonitor monitor) throws RedmineStatusException; - + public int[] getUpdatedIssueIds(Set tasks, Date updatedSince, IProgressMonitor monitor) throws RedmineStatusException; public Issue[] query(Query query, IProgressMonitor monitor) throws RedmineStatusException; - + public int createIssue(Issue issue, IProgressMonitor monitor) throws RedmineStatusException; - public void updateIssue(Issue issue, String comment, TimeEntry timeEntry, IProgressMonitor monitor) throws RedmineStatusException; + public void updateIssue(Issue issue, String comment, Date lastModified, TimeEntry timeEntry, IProgressMonitor monitor) throws RedmineStatusException; public void updateIssue(int issueId, Map issueValues, String comment, TimeEntry timeEntry, IProgressMonitor monitor) throws RedmineStatusException; public InputStream getAttachmentContent(int attachmentId, String fileName, IProgressMonitor monitor) throws RedmineStatusException; - + public void uploadAttachment(int issueId, String fileName, String description, AbstractTaskAttachmentSource source, String comment, IProgressMonitor monitor) throws RedmineStatusException; } diff --git a/net.sf.redmine_mylyn.core/src/net/sf/redmine_mylyn/internal/core/IssueMapper.java b/net.sf.redmine_mylyn.core/src/net/sf/redmine_mylyn/internal/core/IssueMapper.java index 7ee6475..6638c03 100644 --- a/net.sf.redmine_mylyn.core/src/net/sf/redmine_mylyn/internal/core/IssueMapper.java +++ b/net.sf.redmine_mylyn.core/src/net/sf/redmine_mylyn/internal/core/IssueMapper.java @@ -15,8 +15,8 @@ import net.sf.redmine_mylyn.api.model.TimeEntry; import net.sf.redmine_mylyn.api.model.container.CustomValues; import net.sf.redmine_mylyn.common.logging.ILogService; -import net.sf.redmine_mylyn.core.IRedmineExtensionField; import net.sf.redmine_mylyn.core.IRedmineConstants; +import net.sf.redmine_mylyn.core.IRedmineExtensionField; import net.sf.redmine_mylyn.core.RedmineAttribute; import net.sf.redmine_mylyn.core.RedmineCorePlugin; import net.sf.redmine_mylyn.core.RedmineOperation; @@ -35,310 +35,395 @@ public class IssueMapper { - public static void updateTaskData(TaskRepository repository, TaskData taskData, Configuration cfg, Issue issue) throws CoreException { + public static void updateTaskData(final TaskRepository repository, + final TaskData taskData, final Configuration cfg, final Issue issue) + throws CoreException { - TaskAttribute root = taskData.getRoot(); + final TaskAttribute root = taskData.getRoot(); TaskAttribute taskAttribute = null; - + /* Default Attributes */ - for (RedmineAttribute redmineAttribute : RedmineAttribute.values()) { - String taskKey = redmineAttribute.getTaskKey(); - if(taskKey==null) { + for (final RedmineAttribute redmineAttribute : RedmineAttribute + .values()) { + final String taskKey = redmineAttribute.getTaskKey(); + if (taskKey == null) { continue; } - + taskAttribute = root.getAttribute(taskKey); - if (taskAttribute!=null) { - Field field = redmineAttribute.getAttributeField(); - - if(field!=null) { + if (taskAttribute != null) { + final Field field = redmineAttribute.getAttributeField(); + + if (field != null) { try { setValue(taskAttribute, field.get(issue)); - } catch (Exception e) { - IStatus status = RedmineCorePlugin.toStatus(e, Messages.ERRMSG_CANT_READ_PROPERTY_X, redmineAttribute.name()); - ILogService log = RedmineCorePlugin.getLogService(IssueMapper.class); + } catch (final Exception e) { + final IStatus status = RedmineCorePlugin.toStatus(e, + Messages.ERRMSG_CANT_READ_PROPERTY_X, + redmineAttribute.name()); + final ILogService log = RedmineCorePlugin + .getLogService(IssueMapper.class); log.error(e, status.getMessage()); throw new CoreException(status); } } else { switch (redmineAttribute) { case WATCHERS: - for(int watcherId : issue.getWatcherIds()) { + for (final int watcherId : issue.getWatcherIds()) { taskAttribute.addValue(Integer.toString(watcherId)); } break; default: break; } - + } } } - + /* Custom Attributes */ - if(issue.getCustomValues()!=null) { - for (CustomValue customValue : issue.getCustomValues().getAll()) { - taskAttribute = taskData.getRoot().getAttribute(IRedmineConstants.TASK_KEY_PREFIX_ISSUE_CF + customValue.getCustomFieldId()); - if(taskAttribute!=null) { + if (issue.getCustomValues() != null) { + for (final CustomValue customValue : issue.getCustomValues() + .getAll()) { + taskAttribute = taskData.getRoot().getAttribute( + IRedmineConstants.TASK_KEY_PREFIX_ISSUE_CF + + customValue.getCustomFieldId()); + if (taskAttribute != null) { setValue(taskAttribute, customValue.getValue()); } } } - + /* Journals */ - if(issue.getJournals()!=null) { - int jrnlCount=1; - for (Journal journal : issue.getJournals().getAll()) { - TaskCommentMapper mapper = new TaskCommentMapper(); - mapper.setAuthor(repository.createPerson(""+journal.getUserId())); //$NON-NLS-1$ + if (issue.getJournals() != null) { + int jrnlCount = 1; + for (final Journal journal : issue.getJournals().getAll()) { + final TaskCommentMapper mapper = new TaskCommentMapper(); + mapper.setAuthor(repository + .createPerson("" + journal.getUserId())); //$NON-NLS-1$ mapper.setCreationDate(journal.getCreatedOn()); mapper.setText(journal.getNotes()); - String issueUrl = RedmineRepositoryConnector.getTaskUrl(repository.getUrl(), issue.getId()); - mapper.setUrl(issueUrl + String.format(IRedmineConstants.REDMINE_URL_PART_COMMENT, journal.getId())); + final String issueUrl = RedmineRepositoryConnector.getTaskUrl( + repository.getUrl(), issue.getId()); + mapper.setUrl(issueUrl + + String.format( + IRedmineConstants.REDMINE_URL_PART_COMMENT, + journal.getId())); mapper.setNumber(jrnlCount++); mapper.setCommentId(String.valueOf(journal.getId())); - - taskAttribute = taskData.getRoot().createAttribute(TaskAttribute.PREFIX_COMMENT + mapper.getCommentId()); + + taskAttribute = taskData.getRoot().createAttribute( + TaskAttribute.PREFIX_COMMENT + mapper.getCommentId()); mapper.applyTo(taskAttribute); } } /* Attachments */ - if(issue.getAttachments()!=null) { - for (Attachment attachment : issue.getAttachments().getAll()) { - TaskAttachmentMapper mapper = new TaskAttachmentMapper(); + if (issue.getAttachments() != null) { + for (final Attachment attachment : issue.getAttachments().getAll()) { + final TaskAttachmentMapper mapper = new TaskAttachmentMapper(); mapper.setAttachmentId("" + attachment.getId()); //$NON-NLS-1$ - mapper.setAuthor(repository.createPerson(""+attachment.getAuthorId())); //$NON-NLS-1$ + mapper.setAuthor(repository + .createPerson("" + attachment.getAuthorId())); //$NON-NLS-1$ mapper.setDescription(attachment.getDescription()); mapper.setCreationDate(attachment.getCreatedOn()); mapper.setContentType(attachment.getContentType()); mapper.setFileName(attachment.getFilename()); - mapper.setLength((long)attachment.getFilesize()); - mapper.setUrl(String.format(IRedmineConstants.REDMINE_URL_ATTACHMENT_DOWNLOAD, repository.getUrl(), attachment.getId())); - - taskAttribute = taskData.getRoot().createAttribute(TaskAttribute.PREFIX_ATTACHMENT + mapper.getAttachmentId()); + mapper.setLength(attachment.getFilesize()); + mapper.setUrl(String.format( + IRedmineConstants.REDMINE_URL_ATTACHMENT_DOWNLOAD, + repository.getUrl(), attachment.getId())); + + taskAttribute = taskData.getRoot().createAttribute( + TaskAttribute.PREFIX_ATTACHMENT + + mapper.getAttachmentId()); mapper.applyTo(taskAttribute); } } - - if(issue.getTimeEntries()!=null && issue.getTimeEntries().isViewAllowed()) { - //TODO kind/label - taskAttribute = taskData.getRoot().createAttribute(IRedmineConstants.TASK_ATTRIBUTE_TIMEENTRY_TOTAL); - - if(issue.getTimeEntries()!=null) { - taskAttribute.setValue(""+issue.getTimeEntries().getSum()); //$NON-NLS-1$ - - - for (TimeEntry timeEntry : issue.getTimeEntries().getAll()) { - RedmineTaskTimeEntryMapper mapper = new RedmineTaskTimeEntryMapper(); + + if (issue.getTimeEntries() != null + && issue.getTimeEntries().isViewAllowed()) { + // TODO kind/label + taskAttribute = taskData.getRoot().createAttribute( + IRedmineConstants.TASK_ATTRIBUTE_TIMEENTRY_TOTAL); + + if (issue.getTimeEntries() != null) { + taskAttribute.setValue("" + issue.getTimeEntries().getSum()); //$NON-NLS-1$ + + for (final TimeEntry timeEntry : issue.getTimeEntries() + .getAll()) { + final RedmineTaskTimeEntryMapper mapper = new RedmineTaskTimeEntryMapper(); mapper.setTimeEntryId(timeEntry.getId()); - mapper.setUser(repository.createPerson(""+timeEntry.getUserId())); //$NON-NLS-1$ + mapper.setUser(repository + .createPerson("" + timeEntry.getUserId())); //$NON-NLS-1$ mapper.setActivityId(timeEntry.getActivityId()); mapper.setHours(timeEntry.getHours()); mapper.setSpentOn(timeEntry.getSpentOn()); mapper.setComments(timeEntry.getComments()); mapper.setCustomValues(timeEntry.getCustomValues().getAll()); - - taskAttribute = taskData.getRoot().createAttribute(IRedmineConstants.TASK_ATTRIBUTE_TIMEENTRY_PREFIX + mapper.getTimeEntryId()); + + taskAttribute = taskData.getRoot().createAttribute( + IRedmineConstants.TASK_ATTRIBUTE_TIMEENTRY_PREFIX + + mapper.getTimeEntryId()); mapper.applyTo(taskAttribute, cfg); } } - - } - + + } + setTaskKind(issue, cfg, root); - - - } - public static Issue createIssue(TaskRepository repository, TaskData taskData, Set oldAttributes, Configuration cfg) throws CoreException { - Issue issue = taskData.getTaskId().isEmpty() ? new Issue() : new Issue(RedmineUtil.parseIntegerId(taskData.getTaskId())); + public static Issue createIssue(final TaskRepository repository, + final TaskData taskData, final Set oldAttributes, + final Configuration cfg) throws CoreException { + final Issue issue = taskData.getTaskId().isEmpty() ? new Issue() + : new Issue(RedmineUtil.parseIntegerId(taskData.getTaskId())); - TaskAttribute root = taskData.getRoot(); + final TaskAttribute root = taskData.getRoot(); TaskAttribute taskAttribute = null; - + /* Default Attributes */ - for (RedmineAttribute redmineAttribute : RedmineAttribute.values()) { - if(!redmineAttribute.isOperationValue() && !redmineAttribute.isReadOnly()) { + for (final RedmineAttribute redmineAttribute : RedmineAttribute + .values()) { + if (!redmineAttribute.isOperationValue() + && !redmineAttribute.isReadOnly()) { setProperty(redmineAttribute, root, issue); } } - /* Watcher */ - TaskAttribute watchersAttribute = root.getAttribute(RedmineAttribute.WATCHERS.getTaskKey()); - if (watchersAttribute!=null) { - LinkedHashSet watchers = new LinkedHashSet(watchersAttribute.getValues()); - - TaskAttribute newWatcherAttribute = watchersAttribute.getAttribute(RedmineAttribute.WATCHERS_ADD.getTaskKey()); - if (newWatcherAttribute !=null && !newWatcherAttribute.getMetaData().isReadOnly()) { + final TaskAttribute watchersAttribute = root + .getAttribute(RedmineAttribute.WATCHERS.getTaskKey()); + if (watchersAttribute != null) { + final LinkedHashSet watchers = new LinkedHashSet( + watchersAttribute.getValues()); + + final TaskAttribute newWatcherAttribute = watchersAttribute + .getAttribute(RedmineAttribute.WATCHERS_ADD.getTaskKey()); + if (newWatcherAttribute != null + && !newWatcherAttribute.getMetaData().isReadOnly()) { issue.setWatchersAddAllowed(true); - for (String newWatcher : newWatcherAttribute.getValues()) { + for (final String newWatcher : newWatcherAttribute.getValues()) { watchers.add(newWatcher); } } - - TaskAttribute oldWatcherAttribute = watchersAttribute.getAttribute(RedmineAttribute.WATCHERS_REMOVE.getTaskKey()); - if (oldWatcherAttribute !=null && !oldWatcherAttribute.getMetaData().isReadOnly()) { + + final TaskAttribute oldWatcherAttribute = watchersAttribute + .getAttribute(RedmineAttribute.WATCHERS_REMOVE.getTaskKey()); + if (oldWatcherAttribute != null + && !oldWatcherAttribute.getMetaData().isReadOnly()) { issue.setWatchersDeleteAllowed(true); - for (String oldWatcher : oldWatcherAttribute.getValues()) { + for (final String oldWatcher : oldWatcherAttribute.getValues()) { watchers.remove(oldWatcher); } } - - if (watchers.size()>0) { - int[] watcherIds = new int[watchers.size()]; + + if (watchers.size() > 0) { + final int[] watcherIds = new int[watchers.size()]; int lv = 0; - for (String idVal : watchers) { + for (final String idVal : watchers) { watcherIds[lv++] = Integer.parseInt(idVal); } issue.setWatcherIds(watcherIds); } - + } /* Custom Attributes */ - int[] customFieldIds = cfg.getProjects().getById(issue.getProjectId()).getCustomFieldIdsByTrackerId(issue.getTrackerId()); - if(customFieldIds!=null && customFieldIds.length>0) { - CustomValues customValues = new CustomValues(); + final int[] customFieldIds = cfg.getProjects() + .getById(issue.getProjectId()) + .getCustomFieldIdsByTrackerId(issue.getTrackerId()); + if (customFieldIds != null && customFieldIds.length > 0) { + final CustomValues customValues = new CustomValues(); issue.setCustomValues(customValues); - for (int customFieldId : customFieldIds) { - taskAttribute = root.getAttribute(IRedmineConstants.TASK_KEY_PREFIX_ISSUE_CF + customFieldId); - if(taskAttribute!=null) { - customValues.setCustomValue(customFieldId, formatCustomValue(taskAttribute.getValue(), customFieldId, cfg)); + for (final int customFieldId : customFieldIds) { + taskAttribute = root + .getAttribute(IRedmineConstants.TASK_KEY_PREFIX_ISSUE_CF + + customFieldId); + if (taskAttribute != null) { + if (TaskAttribute.TYPE_MULTI_SELECT.equals(taskAttribute + .getMetaData().getType())) { + final List values = taskAttribute.getValues(); + for (final String value : values) { + customValues + .setCustomValue( + customFieldId, + formatCustomValue(value, + customFieldId, cfg)); + + } + } else { + customValues.setCustomValue( + customFieldId, + formatCustomValue(taskAttribute.getValue(), + customFieldId, cfg)); + } } } } - - + /* Operations */ taskAttribute = root.getMappedAttribute(TaskAttribute.OPERATION); if (taskAttribute != null) { - RedmineOperation redmineOperation = RedmineOperation.fromTaskKey(taskAttribute.getValue()); - taskAttribute = root.getAttribute(TaskAttribute.PREFIX_OPERATION + taskAttribute.getValue()); - - if(redmineOperation!=null && taskAttribute!=null) { + final RedmineOperation redmineOperation = RedmineOperation + .fromTaskKey(taskAttribute.getValue()); + taskAttribute = root.getAttribute(TaskAttribute.PREFIX_OPERATION + + taskAttribute.getValue()); + + if (redmineOperation != null && taskAttribute != null) { String value = null; - - if(redmineOperation.isAssociated()) { - taskAttribute = root.getAttribute(redmineOperation.getInputId()); - if(taskAttribute!=null) { + + if (redmineOperation.isAssociated()) { + taskAttribute = root.getAttribute(redmineOperation + .getInputId()); + if (taskAttribute != null) { value = taskAttribute.getValue(); } - } else if(redmineOperation.needsRestoreValue()) { - value = taskAttribute.getMetaData().getValue(IRedmineConstants.TASK_ATTRIBUTE_OPERATION_RESTORE); + } else if (redmineOperation.needsRestoreValue()) { + value = taskAttribute.getMetaData().getValue( + IRedmineConstants.TASK_ATTRIBUTE_OPERATION_RESTORE); } - - if(value!=null) { - RedmineAttribute redmineAttribute = RedmineAttribute.fromTaskKey(redmineOperation.getInputId()); + + if (value != null) { + final RedmineAttribute redmineAttribute = RedmineAttribute + .fromTaskKey(redmineOperation.getInputId()); setProperty(redmineAttribute, root, issue); } } } - + setTaskKind(issue, cfg, root); - - + return issue; } /** * Sets the ${task.kind} mylyn property to the redmine tracker name. - * - * @param issue the redmine issue - * @param cfg the redmine configuration - * @param task the mylyn task + * + * @param issue + * the redmine issue + * @param cfg + * the redmine configuration + * @param task + * the mylyn task */ - private static void setTaskKind(Issue issue, Configuration cfg, TaskAttribute task) { - if (issue.getTrackerId()!=0) { + private static void setTaskKind(final Issue issue, final Configuration cfg, + final TaskAttribute task) { + if (issue.getTrackerId() != 0) { TaskAttribute kind = task.getAttribute(TaskAttribute.TASK_KIND); - if (kind==null) { - kind = task.createAttribute(TaskAttribute.TASK_KIND); + if (kind == null) { + kind = task.createAttribute(TaskAttribute.TASK_KIND); } - kind.setValue(cfg.getTrackers().getById(issue.getTrackerId()).getName()); + kind.setValue(cfg.getTrackers().getById(issue.getTrackerId()) + .getName()); } } - public static TimeEntry createTimeEntry(TaskRepository repository, TaskData taskData, Set oldAttributes, Configuration cfg) throws CoreException { + public static TimeEntry createTimeEntry(final TaskRepository repository, + final TaskData taskData, final Set oldAttributes, + final Configuration cfg) throws CoreException { TimeEntry timeEntry = null; - + try { - String val = getValue(taskData, RedmineAttribute.TIME_ENTRY_HOURS); - if(!val.isEmpty()) { + final String val = getValue(taskData, + RedmineAttribute.TIME_ENTRY_HOURS); + if (!val.isEmpty()) { timeEntry = new TimeEntry(); - + /* Default Attributes */ - long milisec = Long.parseLong(val); - long minutes = milisec/60000; - float hours = minutes/60; - hours += ((float)(minutes%60))/60.0; - + final long milisec = Long.parseLong(val); + final long minutes = milisec / 60000; + float hours = minutes / 60; + hours += minutes % 60 / 60.0; + timeEntry.setHours(hours); - timeEntry.setActivityId(Integer.parseInt(getValue(taskData, RedmineAttribute.TIME_ENTRY_ACTIVITY))); - timeEntry.setComments(getValue(taskData, RedmineAttribute.TIME_ENTRY_COMMENTS)); - + timeEntry.setActivityId(Integer.parseInt(getValue(taskData, + RedmineAttribute.TIME_ENTRY_ACTIVITY))); + timeEntry.setComments(getValue(taskData, + RedmineAttribute.TIME_ENTRY_COMMENTS)); + /* Custom Attributes */ - List customFields = cfg.getCustomFields().getTimeEntryCustomFields(); - if(customFields!=null && customFields.size()>0) { - CustomValues customValues = new CustomValues(); + final List customFields = cfg.getCustomFields() + .getTimeEntryCustomFields(); + if (customFields != null && customFields.size() > 0) { + final CustomValues customValues = new CustomValues(); timeEntry.setCustomValues(customValues); - for (CustomField customField : customFields) { - String value = getValue(taskData, IRedmineConstants.TASK_KEY_PREFIX_TIMEENTRY_CF+customField.getId()); - customValues.setCustomValue(customField.getId(), formatCustomValue(value, customField.getId(), cfg)); + for (final CustomField customField : customFields) { + final String value = getValue(taskData, + IRedmineConstants.TASK_KEY_PREFIX_TIMEENTRY_CF + + customField.getId()); + customValues.setCustomValue( + customField.getId(), + formatCustomValue(value, customField.getId(), + cfg)); } } - + /* Extension/Additional Attributes */ - IRedmineExtensionField additionalFields[] = RedmineCorePlugin.getDefault().getExtensionManager().getAdditionalTimeEntryFields(repository); - for (IRedmineExtensionField additionalField : additionalFields) { - String value = getValue(taskData, IRedmineConstants.TASK_KEY_PREFIX_TIMEENTRY_EX+additionalField.getTaskKey()); - timeEntry.addExtensionValue(additionalField.getSubmitKey(), value); + final IRedmineExtensionField additionalFields[] = RedmineCorePlugin + .getDefault().getExtensionManager() + .getAdditionalTimeEntryFields(repository); + for (final IRedmineExtensionField additionalField : additionalFields) { + final String value = getValue(taskData, + IRedmineConstants.TASK_KEY_PREFIX_TIMEENTRY_EX + + additionalField.getTaskKey()); + timeEntry.addExtensionValue(additionalField.getSubmitKey(), + value); } - + } - } catch (NumberFormatException e) { + } catch (final NumberFormatException e) { timeEntry = null; - IStatus status = RedmineCorePlugin.toStatus(e, Messages.ERRMSG_ILLEGAL_ATTRIBUTE_VALUE); + final IStatus status = RedmineCorePlugin.toStatus(e, + Messages.ERRMSG_ILLEGAL_ATTRIBUTE_VALUE); StatusHandler.log(status); } - + return timeEntry; } - - private static String formatCustomValue(String value, int customFieldId, Configuration cfg) { - CustomField field = cfg.getCustomFields().getById(customFieldId); - if(field!=null) { - switch(field.getFieldFormat()) { - case DATE: value = value.isEmpty() ? "" : RedmineUtil.formatDate(RedmineUtil.parseDate(value)); break; //$NON-NLS-1$ - case BOOL: value = Boolean.parseBoolean(value) ? IRedmineConstants.BOOLEAN_TRUE_SUBMIT_VALUE : IRedmineConstants.BOOLEAN_FALSE_SUBMIT_VALUE; - default: return value; + + private static String formatCustomValue(String value, + final int customFieldId, final Configuration cfg) { + final CustomField field = cfg.getCustomFields().getById(customFieldId); + if (field != null) { + switch (field.getFieldFormat()) { + case DATE: + value = value.isEmpty() ? "" : RedmineUtil.formatDate(RedmineUtil.parseDate(value));break; //$NON-NLS-1$ + case BOOL: + value = Boolean.parseBoolean(value) ? IRedmineConstants.BOOLEAN_TRUE_SUBMIT_VALUE + : IRedmineConstants.BOOLEAN_FALSE_SUBMIT_VALUE; + default: + return value; } } return value; } - - private static String getValue(TaskData taskData, RedmineAttribute redmineAttribute) { + + private static String getValue(final TaskData taskData, + final RedmineAttribute redmineAttribute) { return getValue(taskData, redmineAttribute.getTaskKey()); } - - private static String getValue(TaskData taskData, String taskKey) { - TaskAttribute attribute = taskData.getRoot().getAttribute(taskKey); - return attribute==null ? "" : attribute.getValue(); //$NON-NLS-1$ + + private static String getValue(final TaskData taskData, final String taskKey) { + final TaskAttribute attribute = taskData.getRoot() + .getAttribute(taskKey); + return attribute == null ? "" : attribute.getValue(); //$NON-NLS-1$ } - - private static void setValue(TaskAttribute attribute, Object value) { - if(value==null) { + + private static void setValue(final TaskAttribute attribute, + final Object value) { + if (value == null) { attribute.clearValues(); - } else if(value instanceof String) { - setValue(attribute, (String)value); - } else if(value instanceof Date) { - setValue(attribute, (Date)value); - } else if(value instanceof Integer) { - setValue(attribute, ((Integer)value).intValue()); - } else if(value instanceof int[]) { - for (int intVal : (int[])value) { + } else if (value instanceof String) { + setValue(attribute, (String) value); + } else if (value instanceof Date) { + setValue(attribute, (Date) value); + } else if (value instanceof Integer) { + setValue(attribute, ((Integer) value).intValue()); + } else if (value instanceof int[]) { + for (final int intVal : (int[]) value) { attribute.addValue(Integer.toString(intVal)); } } else { @@ -346,14 +431,22 @@ private static void setValue(TaskAttribute attribute, Object value) { } } - private static void setValue(TaskAttribute attribute, String value) { - if(value==null) { + private static void setValue(final TaskAttribute attribute, + final String value) { + if (value == null) { attribute.setValue(""); //$NON-NLS-1$ - } else if(attribute.getMetaData().getType()==null) { + } else if (attribute.getMetaData().getType() == null) { attribute.setValue(value); - } else if(attribute.getMetaData().getType().equals(TaskAttribute.TYPE_BOOLEAN)) { + } else if (attribute.getMetaData().getType() + .equals(TaskAttribute.TYPE_MULTI_SELECT)) { + attribute.addValue(value); + } else if (attribute.getMetaData().getType() + .equals(TaskAttribute.TYPE_BOOLEAN)) { attribute.setValue(RedmineUtil.parseBoolean(value).toString()); - } else if(attribute.getMetaData().getType().equals(TaskAttribute.TYPE_DATE) || attribute.getMetaData().getType().equals(TaskAttribute.TYPE_DATETIME)) { + } else if (attribute.getMetaData().getType() + .equals(TaskAttribute.TYPE_DATE) + || attribute.getMetaData().getType() + .equals(TaskAttribute.TYPE_DATETIME)) { setValue(attribute, RedmineUtil.parseRedmineDate(value)); } else { attribute.setValue(value); @@ -361,56 +454,89 @@ private static void setValue(TaskAttribute attribute, String value) { } - private static void setValue(TaskAttribute attribute, Date value) { - if(value==null) { + private static void setValue(final TaskAttribute attribute, final Date value) { + if (value == null) { attribute.setValue(""); //$NON-NLS-1$ } else { - attribute.setValue(""+value.getTime()); //$NON-NLS-1$ + attribute.setValue("" + value.getTime()); //$NON-NLS-1$ } } - - private static void setValue(TaskAttribute attribute, int value) { - if (attribute.getId().equals(RedmineAttribute.PROGRESS.getTaskKey()) && attribute.getMetaData().getType()==null) { + + private static void setValue(final TaskAttribute attribute, final int value) { + if (attribute.getId().equals(RedmineAttribute.PROGRESS.getTaskKey()) + && attribute.getMetaData().getType() == null) { attribute.setValue(""); //$NON-NLS-1$ - } else if((attribute.getMetaData().getType()!=null && attribute.getMetaData().getType().equals(TaskAttribute.TYPE_SINGLE_SELECT) || attribute.getMetaData().getType().equals(TaskAttribute.TYPE_PERSON) || attribute.getMetaData().getType().equals(IRedmineConstants.EDITOR_TYPE_PERSON) || attribute.getId().equals(RedmineAttribute.PARENT.getTaskKey())) && value<1) { + } else if ((attribute.getMetaData().getType() != null + && attribute.getMetaData().getType() + .equals(TaskAttribute.TYPE_SINGLE_SELECT) + || attribute.getMetaData().getType() + .equals(TaskAttribute.TYPE_PERSON) + || attribute.getMetaData().getType() + .equals(IRedmineConstants.EDITOR_TYPE_PERSON) || attribute + .getId().equals(RedmineAttribute.PARENT.getTaskKey())) + && value < 1) { attribute.setValue(""); //$NON-NLS-1$ } else { - attribute.setValue(""+value); //$NON-NLS-1$ + attribute.setValue("" + value); //$NON-NLS-1$ } } - - private static void setProperty(RedmineAttribute redmineAttribute, TaskAttribute root, Issue issue) throws CoreException { - Field field = redmineAttribute.getAttributeField(); - if(!redmineAttribute.isReadOnly() && field!=null) { - TaskAttribute taskAttribute = root.getAttribute(redmineAttribute.getTaskKey()); - if(taskAttribute !=null ) { + + private static void setProperty(final RedmineAttribute redmineAttribute, + final TaskAttribute root, final Issue issue) throws CoreException { + final Field field = redmineAttribute.getAttributeField(); + if (!redmineAttribute.isReadOnly() && field != null) { + final TaskAttribute taskAttribute = root + .getAttribute(redmineAttribute.getTaskKey()); + if (taskAttribute != null) { try { - switch(redmineAttribute) { + switch (redmineAttribute) { case SUMMARY: case DESCRIPTION: - case COMMENT: field.set(issue, taskAttribute.getValue()); break; - case PROGRESS:field.setInt(issue, taskAttribute.getValue().isEmpty() ? 0 : Integer.parseInt(taskAttribute.getValue())); break; + case COMMENT: + field.set(issue, taskAttribute.getValue()); + break; + case PROGRESS: + field.setInt( + issue, + taskAttribute.getValue().isEmpty() ? 0 + : Integer.parseInt(taskAttribute + .getValue())); + break; case ESTIMATED: - if (!taskAttribute.getValue().isEmpty()) - field.set(issue, new Float(taskAttribute.getValue())); + if (!taskAttribute.getValue().isEmpty()) { + field.set(issue, + new Float(taskAttribute.getValue())); + } break; default: - if(redmineAttribute.getType().equals(TaskAttribute.TYPE_SINGLE_SELECT) || redmineAttribute.getType().equals(TaskAttribute.TYPE_PERSON) || redmineAttribute.getType().equals(IRedmineConstants.EDITOR_TYPE_PERSON) || redmineAttribute==RedmineAttribute.PARENT) { - int idVal = RedmineUtil.parseIntegerId(taskAttribute.getValue()); - if(idVal>0) { + if (redmineAttribute.getType().equals( + TaskAttribute.TYPE_SINGLE_SELECT) + || redmineAttribute.getType().equals( + TaskAttribute.TYPE_PERSON) + || redmineAttribute.getType().equals( + IRedmineConstants.EDITOR_TYPE_PERSON) + || redmineAttribute == RedmineAttribute.PARENT) { + final int idVal = RedmineUtil + .parseIntegerId(taskAttribute.getValue()); + if (idVal > 0) { field.setInt(issue, idVal); } } else - - if(redmineAttribute.getType().equals(TaskAttribute.TYPE_DATE)) { - if (!taskAttribute.getValue().isEmpty()) { - field.set(issue, RedmineUtil.parseDate(taskAttribute.getValue())); + + if (redmineAttribute.getType().equals( + TaskAttribute.TYPE_DATE)) { + if (!taskAttribute.getValue().isEmpty()) { + field.set(issue, RedmineUtil + .parseDate(taskAttribute.getValue())); + } } - } } - } catch (Exception e) { - IStatus status = RedmineCorePlugin.toStatus(e, Messages.ERRMSG_CANT_READ_PROPERTY_X, redmineAttribute.name()); - ILogService log = RedmineCorePlugin.getLogService(IssueMapper.class); + } catch (final Exception e) { + final IStatus status = RedmineCorePlugin.toStatus(e, + Messages.ERRMSG_CANT_READ_PROPERTY_X, + redmineAttribute.name()); + final ILogService log = RedmineCorePlugin + .getLogService(IssueMapper.class); log.error(e, status.getMessage()); throw new CoreException(status); } diff --git a/net.sf.redmine_mylyn.core/src/net/sf/redmine_mylyn/internal/core/client/Client.java b/net.sf.redmine_mylyn.core/src/net/sf/redmine_mylyn/internal/core/client/Client.java index 87d30d5..3f76879 100644 --- a/net.sf.redmine_mylyn.core/src/net/sf/redmine_mylyn/internal/core/client/Client.java +++ b/net.sf.redmine_mylyn.core/src/net/sf/redmine_mylyn/internal/core/client/Client.java @@ -29,156 +29,156 @@ import org.eclipse.mylyn.tasks.core.data.AbstractTaskAttachmentSource; public class Client implements IClient { - + private final IRedmineApiClient apiClient; - public Client(IRedmineApiClient apiClient) { - this.apiClient = apiClient; + public Client(final IRedmineApiClient apiClient) { + this.apiClient = apiClient; } - + @Override public Configuration getConfiguration(){ return apiClient.getConfiguration(); } - + @Override - public void updateConfiguration(IProgressMonitor monitor) throws RedmineStatusException { + public void updateConfiguration(final IProgressMonitor monitor) throws RedmineStatusException { try { apiClient.updateConfiguration(monitor); - } catch (RedmineApiErrorException e) { + } catch (final RedmineApiErrorException e) { throw new RedmineStatusException(e, Messages.ERRMSG_CONFIGURATION_UPDATE_FAILED, e.getMessage()); } } - + @Override - public RedmineServerVersion checkClientConnection(IProgressMonitor monitor) throws RedmineStatusException { - + public RedmineServerVersion checkClientConnection(final IProgressMonitor monitor) throws RedmineStatusException { + RedmineServerVersion version; try { version = apiClient.detectServerVersion(monitor); - } catch (RedmineApiErrorException e) { + } catch (final RedmineApiErrorException e) { throw new RedmineStatusException(e); } - + return version; } - + @Override - public Issue getIssue(int id, IProgressMonitor monitor) throws RedmineStatusException { + public Issue getIssue(final int id, final IProgressMonitor monitor) throws RedmineStatusException { try { return apiClient.getIssue(id, monitor); - } catch (RedmineApiErrorException e) { + } catch (final RedmineApiErrorException e) { throw new RedmineStatusException(e); } } - + @Override - public Issue[] getIssues(Set taskIds, IProgressMonitor monitor) throws RedmineStatusException { - int[] ids = new int[taskIds.size()]; + public Issue[] getIssues(final Set taskIds, final IProgressMonitor monitor) throws RedmineStatusException { + final int[] ids = new int[taskIds.size()]; int lv=0; - for(String taskId : taskIds) { - int id = RedmineUtil.parseIntegerId(taskId); + for(final String taskId : taskIds) { + final int id = RedmineUtil.parseIntegerId(taskId); if(id>0) { ids[lv++] = id; } } - + try { return apiClient.getIssues(monitor, ids); - } catch (RedmineApiErrorException e) { + } catch (final RedmineApiErrorException e) { throw new RedmineStatusException(e); } } @Override - public int[] getUpdatedIssueIds(Set tasks, Date updatedSince, IProgressMonitor monitor) throws RedmineStatusException { - int[] ids = new int[tasks.size()]; + public int[] getUpdatedIssueIds(final Set tasks, final Date updatedSince, final IProgressMonitor monitor) throws RedmineStatusException { + final int[] ids = new int[tasks.size()]; int lv=0; - for(ITask task : tasks) { + for(final ITask task : tasks) { ids[lv++] = RedmineUtil.parseIntegerId(task.getTaskId()); } - + try { return apiClient.getUpdatedIssueIds(ids, updatedSince, monitor); - } catch (RedmineApiErrorException e) { + } catch (final RedmineApiErrorException e) { throw new RedmineStatusException(e); } } - + @Override - public Issue[] query(Query query, IProgressMonitor monitor) throws RedmineStatusException { + public Issue[] query(final Query query, final IProgressMonitor monitor) throws RedmineStatusException { try { return apiClient.query(query, monitor); - } catch (RedmineApiErrorException e) { + } catch (final RedmineApiErrorException e) { throw new RedmineStatusException(e); } } @Override - public int createIssue(Issue issue, IProgressMonitor monitor) throws RedmineStatusException { - ErrrorCollector errorCollector = new ErrrorCollector(); + public int createIssue(final Issue issue, final IProgressMonitor monitor) throws RedmineStatusException { + final ErrrorCollector errorCollector = new ErrrorCollector(); try { return apiClient.createIssue(issue, errorCollector, monitor).getId(); - } catch (RedmineApiErrorException e) { + } catch (final RedmineApiErrorException e) { throw new RedmineStatusException(e); - } catch (RedmineApiInvalidDataException e) { - IStatus status = new Status(IStatus.ERROR, RedmineCorePlugin.PLUGIN_ID, errorCollector.getErrorString(), e); + } catch (final RedmineApiInvalidDataException e) { + final IStatus status = new Status(IStatus.ERROR, RedmineCorePlugin.PLUGIN_ID, errorCollector.getErrorString(), e); throw new RedmineStatusException(status); } } - + @Override - public void updateIssue(Issue issue, String comment, TimeEntry timeEntry, IProgressMonitor monitor) throws RedmineStatusException { - ErrrorCollector errorCollector = new ErrrorCollector(); + public void updateIssue(final Issue issue, final String comment, final Date lastModified, final TimeEntry timeEntry, final IProgressMonitor monitor) throws RedmineStatusException { + final ErrrorCollector errorCollector = new ErrrorCollector(); try { - apiClient.updateIssue(issue, comment, timeEntry, errorCollector, monitor); - } catch (RedmineApiErrorException e) { + apiClient.updateIssue(issue, comment, lastModified, timeEntry, errorCollector, monitor); + } catch (final RedmineApiErrorException e) { throw new RedmineStatusException(e); - } catch (RedmineApiInvalidDataException e) { - IStatus status = new Status(IStatus.ERROR, RedmineCorePlugin.PLUGIN_ID, errorCollector.getErrorString(), e); + } catch (final RedmineApiInvalidDataException e) { + final IStatus status = new Status(IStatus.ERROR, RedmineCorePlugin.PLUGIN_ID, errorCollector.getErrorString(), e); throw new RedmineStatusException(status); } } - + @Override - public void updateIssue(int issueId, Map issueValues, String comment, TimeEntry timeEntry, IProgressMonitor monitor) throws RedmineStatusException { - ErrrorCollector errorCollector = new ErrrorCollector(); + public void updateIssue(final int issueId, final Map issueValues, final String comment, final TimeEntry timeEntry, final IProgressMonitor monitor) throws RedmineStatusException { + final ErrrorCollector errorCollector = new ErrrorCollector(); try { apiClient.updateIssue(issueId, issueValues, comment, timeEntry, errorCollector, monitor); - } catch (RedmineApiErrorException e) { + } catch (final RedmineApiErrorException e) { throw new RedmineStatusException(e); - } catch (RedmineApiInvalidDataException e) { - IStatus status = new Status(IStatus.ERROR, RedmineCorePlugin.PLUGIN_ID, errorCollector.getErrorString(), e); + } catch (final RedmineApiInvalidDataException e) { + final IStatus status = new Status(IStatus.ERROR, RedmineCorePlugin.PLUGIN_ID, errorCollector.getErrorString(), e); throw new RedmineStatusException(status); } } - + @Override - public void uploadAttachment(int issueId, String fileName, String description, AbstractTaskAttachmentSource source, String comment, IProgressMonitor monitor) throws RedmineStatusException { - ErrrorCollector errorCollector = new ErrrorCollector(); + public void uploadAttachment(final int issueId, final String fileName, final String description, final AbstractTaskAttachmentSource source, final String comment, final IProgressMonitor monitor) throws RedmineStatusException { + final ErrrorCollector errorCollector = new ErrrorCollector(); try { - Attachment attachment = new Attachment(); + final Attachment attachment = new Attachment(); attachment.setFilename(fileName); attachment.setDescription(description); attachment.setFilesize(source.getLength()); attachment.setContentType(source.getContentType()); apiClient.uploadAttachment(issueId, attachment, source.createInputStream(monitor), comment, errorCollector, monitor); - } catch (CoreException e) { + } catch (final CoreException e) { new RedmineStatusException(e.getStatus()); - } catch (RedmineApiErrorException e) { + } catch (final RedmineApiErrorException e) { throw new RedmineStatusException(e); - } catch (RedmineApiInvalidDataException e) { - IStatus status = new Status(IStatus.ERROR, RedmineCorePlugin.PLUGIN_ID, errorCollector.getErrorString(), e); + } catch (final RedmineApiInvalidDataException e) { + final IStatus status = new Status(IStatus.ERROR, RedmineCorePlugin.PLUGIN_ID, errorCollector.getErrorString(), e); throw new RedmineStatusException(status); } } - + @Override - public InputStream getAttachmentContent(int attachmentId, String fileName, IProgressMonitor monitor) throws RedmineStatusException { + public InputStream getAttachmentContent(final int attachmentId, final String fileName, final IProgressMonitor monitor) throws RedmineStatusException { try { return apiClient.getAttachmentContent(attachmentId, fileName, monitor); - } catch (RedmineApiErrorException e) { + } catch (final RedmineApiErrorException e) { throw new RedmineStatusException(e); } } diff --git a/net.sf.redmine_mylyn.feature/feature.xml b/net.sf.redmine_mylyn.feature/feature.xml index 44ddc2e..c2502f8 100644 --- a/net.sf.redmine_mylyn.feature/feature.xml +++ b/net.sf.redmine_mylyn.feature/feature.xml @@ -2,7 +2,7 @@ @@ -81,8 +81,8 @@ version="0.0.0" fragment="true" unpack="false"/> - - net.sf.redmine_mylyn net.sf.redmine_mylyn.parent - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT net.sf.redmine_mylyn.feature diff --git a/net.sf.redmine_mylyn.p2repository/category.xml b/net.sf.redmine_mylyn.p2repository/category.xml index c0c0707..9602e63 100644 --- a/net.sf.redmine_mylyn.p2repository/category.xml +++ b/net.sf.redmine_mylyn.p2repository/category.xml @@ -3,7 +3,7 @@ Provides Task List integration, offline support and rich editing for the open source Redmine project management. - + diff --git a/net.sf.redmine_mylyn.p2repository/pom.xml b/net.sf.redmine_mylyn.p2repository/pom.xml index 49ff5ae..52c0dd6 100644 --- a/net.sf.redmine_mylyn.p2repository/pom.xml +++ b/net.sf.redmine_mylyn.p2repository/pom.xml @@ -7,7 +7,7 @@ net.sf.redmine_mylyn net.sf.redmine_mylyn.parent - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT net.sf.redmine_mylyn.p2repository diff --git a/net.sf.redmine_mylyn.ui/.gitignore b/net.sf.redmine_mylyn.ui/.gitignore new file mode 100644 index 0000000..1dd3331 --- /dev/null +++ b/net.sf.redmine_mylyn.ui/.gitignore @@ -0,0 +1,2 @@ +/target/ +/target/ diff --git a/net.sf.redmine_mylyn.ui/.settings/org.eclipse.jdt.core.prefs b/net.sf.redmine_mylyn.ui/.settings/org.eclipse.jdt.core.prefs index 1b7e5fa..c537b63 100644 --- a/net.sf.redmine_mylyn.ui/.settings/org.eclipse.jdt.core.prefs +++ b/net.sf.redmine_mylyn.ui/.settings/org.eclipse.jdt.core.prefs @@ -1,4 +1,3 @@ -#Sat Jun 19 17:07:45 CEST 2010 eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 diff --git a/net.sf.redmine_mylyn.ui/META-INF/MANIFEST.MF b/net.sf.redmine_mylyn.ui/META-INF/MANIFEST.MF index b0ad299..ef41aa4 100644 --- a/net.sf.redmine_mylyn.ui/META-INF/MANIFEST.MF +++ b/net.sf.redmine_mylyn.ui/META-INF/MANIFEST.MF @@ -2,18 +2,18 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: net.sf.redmine_mylyn.ui;singleton:=true -Bundle-Version: 0.4.0.qualifier +Bundle-Version: 0.4.1.qualifier Bundle-Activator: net.sf.redmine_mylyn.ui.RedmineUiPlugin Bundle-Vendor: %Bundle-Vendor Require-Bundle: org.eclipse.core.runtime;bundle-version="3.5.0", - net.sf.redmine_mylyn.api;bundle-version="0.4.0", + net.sf.redmine_mylyn.api;bundle-version="0.4.1", org.eclipse.mylyn.tasks.ui;bundle-version="3.5.0", - net.sf.redmine_mylyn.core;bundle-version="0.4.0", + net.sf.redmine_mylyn.core;bundle-version="0.4.1", org.eclipse.mylyn.tasks.core;bundle-version="3.5.0", org.eclipse.ui.forms;bundle-version="3.4.0", org.eclipse.ui;bundle-version="3.5.0", org.eclipse.mylyn.commons.core;bundle-version="3.5.0", - net.sf.redmine_mylyn.common;bundle-version="0.4.0", + net.sf.redmine_mylyn.common;bundle-version="0.4.1", org.eclipse.osgi.services;bundle-version="3.2.0", org.eclipse.mylyn.commons.net;bundle-version="3.5.0", org.eclipse.ui.editors;bundle-version="3.5.0", diff --git a/net.sf.redmine_mylyn.ui/plugin.xml b/net.sf.redmine_mylyn.ui/plugin.xml index 395551a..c0dcd1b 100644 --- a/net.sf.redmine_mylyn.ui/plugin.xml +++ b/net.sf.redmine_mylyn.ui/plugin.xml @@ -1,6 +1,7 @@ + net.sf.redmine_mylyn net.sf.redmine_mylyn.parent - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT net.sf.redmine_mylyn.ui diff --git a/net.sf.redmine_mylyn.ui/schema/net.sf.redmine_mylyn.editor.modelchanger.exsd b/net.sf.redmine_mylyn.ui/schema/net.sf.redmine_mylyn.editor.modelchanger.exsd new file mode 100644 index 0000000..b58210a --- /dev/null +++ b/net.sf.redmine_mylyn.ui/schema/net.sf.redmine_mylyn.editor.modelchanger.exsd @@ -0,0 +1,102 @@ + + + + + + + + + This extenion point is called whenever a redmine task model is changed. Thus an implementor may change rules if a model change occurrs. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [Enter the first release in which this extension point appears.] + + + + + + + + + [Enter extension point usage example here.] + + + + + + + + + [Enter API information here.] + + + + + + + + + [Enter information about supplied implementation of this extension point.] + + + + + diff --git a/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/RedminePersonProposalProvider.java b/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/RedminePersonProposalProvider.java index 6c92371..0863e02 100644 --- a/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/RedminePersonProposalProvider.java +++ b/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/RedminePersonProposalProvider.java @@ -29,33 +29,33 @@ public class RedminePersonProposalProvider implements IContentProposalProvider { private Set addressSet = null; - private String repositoryUrl; + private final String repositoryUrl; - private String connectorKind; + private final String connectorKind; private Map proposals; - + private Configuration configuration; - public RedminePersonProposalProvider(ITask task, TaskData taskData) { + public RedminePersonProposalProvider(final ITask task, final TaskData taskData) { repositoryUrl = taskData.getRepositoryUrl(); connectorKind = taskData.getConnectorKind(); if (repositoryUrl != null && connectorKind != null) { - TaskRepository repository = TasksUi.getRepositoryManager().getRepository(connectorKind, repositoryUrl); + final TaskRepository repository = TasksUi.getRepositoryManager().getRepository(connectorKind, repositoryUrl); if (repository != null) { - AbstractRepositoryConnector connector = TasksUi.getRepositoryConnector(connectorKind); + final AbstractRepositoryConnector connector = TasksUi.getRepositoryConnector(connectorKind); if (connector!=null && connector instanceof RedmineRepositoryConnector) { try { configuration = ((RedmineRepositoryConnector)connector).getClientManager().getClient(repository).getConfiguration(); - } catch (RedmineStatusException e) { + } catch (final RedmineStatusException e) { RedmineUiPlugin.getLogService(getClass()).error(e, "Can't fetch repository configuration"); //$NON-NLS-1$ } } - - AuthenticationCredentials credentials = repository.getCredentials(AuthenticationType.REPOSITORY); + + final AuthenticationCredentials credentials = repository.getCredentials(AuthenticationType.REPOSITORY); if (credentials != null && credentials.getUserName().length() > 0) { currentUser = credentials.getUserName(); } @@ -63,43 +63,44 @@ public RedminePersonProposalProvider(ITask task, TaskData taskData) { } } - public RedminePersonProposalProvider(ITask task, TaskData taskData, Map proposals) { + public RedminePersonProposalProvider(final ITask task, final TaskData taskData, final Map proposals) { this(task, taskData); this.proposals = proposals; - + } - - public void setProposals( Map proposals ) { + + public void setProposals( final Map proposals ) { this.proposals = proposals; - this.addressSet = null; + addressSet = null; } - - public IContentProposal[] getProposals(String contents, int position) { + + @Override + public IContentProposal[] getProposals(final String contents, final int position) { if (contents == null) { throw new IllegalArgumentException(); } - String searchText = contents.toLowerCase(); + final String searchText = contents.toLowerCase(); + + final Set addressSet = new HashSet(); - Set addressSet = new HashSet(); - - for (String address : getAddressSet()) { + for (final String address : getAddressSet()) { if (address.toLowerCase().contains(searchText)) { addressSet.add(address); } } - - IContentProposal[] result = new IContentProposal[addressSet.size()]; + + final IContentProposal[] result = new IContentProposal[addressSet.size()]; int i = 0; for (final String address : addressSet) { result[i++] = new RedminePersonContentProposal( address, - currentUser != null && address.contains(currentUser), + currentUser != null && address.contains(currentUser), address, address.length()); } - + Arrays.sort(result); return result; } @@ -110,16 +111,21 @@ private Set getAddressSet() { } addressSet = new HashSet(); - + if (proposals != null && !proposals.isEmpty()) { - for (Entry entry : proposals.entrySet()) { - - String name = entry.getValue(); + for (final Entry entry : proposals.entrySet()) { + + final String name = entry.getValue(); if (name!=null && !name.isEmpty()) { User user = null; - + if (configuration!=null && (user=configuration.getUsers().getById(RedmineUtil.parseIntegerId(entry.getKey())))!=null) { - addressSet.add(RedmineUtil.formatUserPresentation(user.getLogin(), name)); + final String login = user.getLogin(); + if (login.isEmpty()) { + addressSet.add(RedmineUtil.formatUserPresentation(name, name)); + } else { + addressSet.add(RedmineUtil.formatUserPresentation(user.getLogin(), name)); + } } else { addressSet.add(RedmineUtil.formatUserPresentation(entry.getKey(), name)); } diff --git a/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/editor/RedminePersonEditor.java b/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/editor/RedminePersonEditor.java index 894f255..907c17c 100644 --- a/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/editor/RedminePersonEditor.java +++ b/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/editor/RedminePersonEditor.java @@ -30,28 +30,28 @@ public class RedminePersonEditor extends AbstractAttributeEditor { protected Text text; protected RedminePersonProposalProvider contentProposalProvider; -// private final TaskDataModelListener modelListener; + // private final TaskDataModelListener modelListener; - public RedminePersonEditor(TaskDataModel manager, TaskAttribute taskAttribute) { + public RedminePersonEditor(final TaskDataModel manager, final TaskAttribute taskAttribute) { super(manager, taskAttribute); setLayoutHint(new LayoutHint(RowSpan.SINGLE, ColumnSpan.SINGLE)); -// modelListener = new TaskDataModelListener() { -// @Override -// public void attributeChanged(TaskDataModelEvent event) { -// if(event.getTaskAttribute().getId().equals(getTaskAttribute().getId())) { -// IRepositoryPerson person = getAttributeMapper().getRepositoryPerson(event.getTaskAttribute()); -// String personString = RedmineUtil.formatUserPresentation(person); -// if (!text.getText().equals(personString)) { -// text.setText(personString); -// } -// } -// } -// }; + // modelListener = new TaskDataModelListener() { + // @Override + // public void attributeChanged(TaskDataModelEvent event) { + // if(event.getTaskAttribute().getId().equals(getTaskAttribute().getId())) { + // IRepositoryPerson person = getAttributeMapper().getRepositoryPerson(event.getTaskAttribute()); + // String personString = RedmineUtil.formatUserPresentation(person); + // if (!text.getText().equals(personString)) { + // text.setText(personString); + // } + // } + // } + // }; } - + @Override - public void createControl(Composite parent, FormToolkit toolkit) { + public void createControl(final Composite parent, final FormToolkit toolkit) { if (isReadOnly()) { text = new Text(parent, SWT.FLAT | SWT.READ_ONLY); text.setData(FormToolkit.KEY_DRAW_BORDER, Boolean.FALSE); @@ -61,38 +61,39 @@ public void createControl(Composite parent, FormToolkit toolkit) { text = toolkit.createText(parent, getValue(), SWT.FLAT); text.setToolTipText(getDescription()); text.addModifyListener(new ModifyListener() { - public void modifyText(ModifyEvent e) { + @Override + public void modifyText(final ModifyEvent e) { setValue(text.getText()); } }); } toolkit.adapt(text, false, false); setControl(text); - + attachContentProposalProvider(); -// text.addDisposeListener(new DisposeListener() { -// @Override -// public void widgetDisposed(DisposeEvent e) { -// getModel().removeModelListener(modelListener); -// } -// }); -// getModel().addModelListener(modelListener); -} + // text.addDisposeListener(new DisposeListener() { + // @Override + // public void widgetDisposed(DisposeEvent e) { + // getModel().removeModelListener(modelListener); + // } + // }); + // getModel().addModelListener(modelListener); + } public String getValue() { return RedmineUtil.formatUserPresentation(getAttributeMapper().getRepositoryPerson(getTaskAttribute())); } - public void setValue(String text) { + public void setValue(final String text) { if (text.isEmpty()) { getTaskAttribute().setValue(text); attributeChanged(); } else { - - String value = RedmineUtil.findUserLogin(text); + + final String value = RedmineUtil.findUserLogin(text); if(value!=null && !value.isEmpty()) { - IRepositoryPerson person = getModel().getTaskRepository().createPerson(value); + final IRepositoryPerson person = getModel().getTaskRepository().createPerson(value); getAttributeMapper().setRepositoryPerson(getTaskAttribute(), person); attributeChanged(); } @@ -102,26 +103,33 @@ public void setValue(String text) { @Override public void refresh() { - Map persons = getAttributeMapper().getOptions(getTaskAttribute()); + final Map persons = getAttributeMapper().getOptions(getTaskAttribute()); contentProposalProvider.setProposals(persons); - + if (!persons.containsKey(getTaskAttribute().getValue())) { text.setText(""); + } else { + text.setText(RedmineUtil.formatUserPresentation(getAttributeMapper().getRepositoryPerson(getTaskAttribute()))); } } - + + @Override + protected boolean shouldAutoRefresh() { + return true; + } + private void attachContentProposalProvider() { - Map persons = getAttributeMapper().getOptions(getTaskAttribute()); - + final Map persons = getAttributeMapper().getOptions(getTaskAttribute()); + contentProposalProvider = new RedminePersonProposalProvider(getModel().getTask(), getTaskAttribute().getTaskData(), persons); - ILabelProvider labelPropsalProvider = new RedminePersonProposalLabelProvider(); - - ContentAssistCommandAdapter adapter = new ContentAssistCommandAdapter(text, + final ILabelProvider labelPropsalProvider = new RedminePersonProposalLabelProvider(); + + final ContentAssistCommandAdapter adapter = new ContentAssistCommandAdapter(text, new TextContentAdapter(), contentProposalProvider, ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS, new char[0], true); - + adapter.setLabelProvider(labelPropsalProvider); adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE); - + } } diff --git a/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/editor/RedmineTaskEditorPage.java b/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/editor/RedmineTaskEditorPage.java index 3023407..95c5f75 100644 --- a/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/editor/RedmineTaskEditorPage.java +++ b/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/editor/RedmineTaskEditorPage.java @@ -62,6 +62,7 @@ public class RedmineTaskEditorPage extends AbstractTaskEditorPage { private final TaskDataModelListener trackerAttributeListener; private final TaskDataModelListener validatorAttributeListener; private final TaskDataModelListener statusAttributeListener; + private final TaskDataModelListener customListener; private TaskDataValidator validator; // @@ -85,8 +86,7 @@ public RedmineTaskEditorPage(TaskEditor editor) { trackerAttributeListener = new TrackerTaskDataModelListener(); validatorAttributeListener = new ValidatorTaskDataModelListener(); statusAttributeListener = new StatusTaskDataModelListener(); - - + customListener = new TaskDataModelListenerExtension(); } @@ -102,6 +102,7 @@ public void init(IEditorSite site, IEditorInput input) { getModel().addModelListener(trackerAttributeListener); getModel().addModelListener(validatorAttributeListener); getModel().addModelListener(statusAttributeListener); + getModel().addModelListener(customListener); } @Override @@ -110,6 +111,7 @@ public void dispose() { getModel().removeModelListener(trackerAttributeListener); getModel().removeModelListener(validatorAttributeListener); getModel().removeModelListener(statusAttributeListener); + getModel().removeModelListener(customListener); super.dispose(); } diff --git a/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/editor/TaskDataModelListenerExtension.java b/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/editor/TaskDataModelListenerExtension.java new file mode 100644 index 0000000..830f123 --- /dev/null +++ b/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/editor/TaskDataModelListenerExtension.java @@ -0,0 +1,72 @@ +package net.sf.redmine_mylyn.internal.ui.editor; + +import java.util.ArrayList; +import java.util.List; + +import net.sf.redmine_mylyn.common.logging.ILogService; +import net.sf.redmine_mylyn.ui.RedmineUiPlugin; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.ISafeRunnable; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.mylyn.tasks.core.data.TaskDataModelEvent; +import org.eclipse.mylyn.tasks.core.data.TaskDataModelListener; + +public class TaskDataModelListenerExtension extends TaskDataModelListener { + + private static final ILogService LOG_SERVICE = RedmineUiPlugin + .getLogService(TaskDataModelListenerExtension.class); + + private List extensionPoints; + + @Override + public void attributeChanged(final TaskDataModelEvent event) { + checkExtensionPoints(); + for (final TaskDataModelListener taskDataModelListener : extensionPoints) { + executeExtension(taskDataModelListener, event); + } + } + + private void checkExtensionPoints() { + if (extensionPoints == null) { + final List handlers = new ArrayList(); + final IConfigurationElement[] config = Platform + .getExtensionRegistry().getConfigurationElementsFor( + "net.sf.redmine_mylyn.editor.modelchanger"); + try { + for (final IConfigurationElement configElement : config) { + final Object o = configElement.createExecutableExtension("class"); + if (o instanceof TaskDataModelListener) { + handlers.add((TaskDataModelListener) o); + } + } + } catch (final CoreException e) { + LOG_SERVICE + .error(e, + "Error configuring extension point for model change events."); + } + extensionPoints = handlers; + } + } + + private void executeExtension(final TaskDataModelListener o, + final TaskDataModelEvent event) { + final ISafeRunnable runnable = new ISafeRunnable() { + @Override + public void handleException(final Throwable e) { + LOG_SERVICE + .error(e, + "Exception in client implementation of model change event handler."); + } + + @Override + public void run() throws Exception { + o.attributeChanged(event); + } + }; + SafeRunner.run(runnable); + } + +} diff --git a/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/messages.properties b/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/messages.properties index ec7c700..6008a86 100644 --- a/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/messages.properties +++ b/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/messages.properties @@ -33,7 +33,7 @@ LBL_APIKEY=API-Key LBL_ENABLE=Enable LBL_SPECIAL_QUERY_PARAM_X=<< {0} >> LBL_X_ALL_PROJECTS={0} (all projects) -LBL_X_PROJECT_X={0} (Project {1}) +LBL_X_PROJECT_X={0} ("{1}") NEW_TIMEENTRY_PART=New Time Entry PLANNING_PART=Planning QUERY_TITLE=Query Title diff --git a/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/query/ProjectProvider.java b/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/query/ProjectProvider.java new file mode 100644 index 0000000..5fe915c --- /dev/null +++ b/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/query/ProjectProvider.java @@ -0,0 +1,7 @@ +package net.sf.redmine_mylyn.internal.ui.query; + +import net.sf.redmine_mylyn.api.model.container.Projects; + +public interface ProjectProvider { + Projects getProjects(); +} \ No newline at end of file diff --git a/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/query/RedmineLabelProvider.java b/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/query/RedmineLabelProvider.java index 27972d8..a11808a 100644 --- a/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/query/RedmineLabelProvider.java +++ b/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/query/RedmineLabelProvider.java @@ -11,13 +11,17 @@ public class RedmineLabelProvider extends LabelProvider { private String title = null; + private final ProjectProvider projectProvider; - public RedmineLabelProvider() { - super(); + public RedmineLabelProvider(String title, ProjectProvider projectProvider) { + this(projectProvider); + this.title = title; } - public RedmineLabelProvider(String title) { - this.title = title; + public RedmineLabelProvider( + ProjectProvider projectProvider) { + super(); + this.projectProvider = projectProvider; } @Override @@ -27,7 +31,7 @@ public String getText(Object element) { if(storedQuery.getProjectId()<1) { return MessageFormat.format(Messages.LBL_X_ALL_PROJECTS, storedQuery.getName()); } else { - return MessageFormat.format(Messages.LBL_X_PROJECT_X, storedQuery.getName(), storedQuery.getProjectId()); + return MessageFormat.format(Messages.LBL_X_PROJECT_X, storedQuery.getName(), projectProvider.getProjects().getById(storedQuery.getProjectId()).getName()); } } @@ -42,5 +46,4 @@ public String getText(Object element) { return super.getText(element); } - } diff --git a/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/query/RedmineRepositoryQueryPage.java b/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/query/RedmineRepositoryQueryPage.java index a3e93cd..edba53e 100644 --- a/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/query/RedmineRepositoryQueryPage.java +++ b/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/query/RedmineRepositoryQueryPage.java @@ -14,6 +14,7 @@ import net.sf.redmine_mylyn.api.model.CustomField; import net.sf.redmine_mylyn.api.model.Project; import net.sf.redmine_mylyn.api.model.Tracker; +import net.sf.redmine_mylyn.api.model.container.Projects; import net.sf.redmine_mylyn.api.query.CompareOperator; import net.sf.redmine_mylyn.api.query.IQueryField; import net.sf.redmine_mylyn.api.query.Query; @@ -47,7 +48,7 @@ import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; -public class RedmineRepositoryQueryPage extends AbstractRedmineRepositoryQueryPage { +public class RedmineRepositoryQueryPage extends AbstractRedmineRepositoryQueryPage implements ProjectProvider { private static final String TITLE = Messages.CREATE_QUERY; @@ -182,7 +183,7 @@ private Control createInputControl(Composite parent, QueryField definition, IQue } ListViewer list = new ListViewer(parent, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL); - list.setLabelProvider(new RedmineLabelProvider(constrArg)); + list.setLabelProvider(new RedmineLabelProvider(constrArg, this)); list.setContentProvider(new RedmineContentProvider(constrArg)); list.getControl().setEnabled(false); @@ -211,7 +212,7 @@ private ComboViewer createOperatorComboViewer(Composite parent, QueryField defin String defaultValue = definition.isRequired() ? null : Messages.DISABLED; combo.setContentProvider(new RedmineContentProvider(defaultValue)); - combo.setLabelProvider(new RedmineLabelProvider()); + combo.setLabelProvider(new RedmineLabelProvider(this)); combo.setInput(definition.getCompareOperators()); combo.setSelection(new StructuredSelection(combo.getElementAt(0))); @@ -499,5 +500,10 @@ public void applyTo(IRepositoryQuery repositoryQuery) { public String getQueryTitle() { return (titleText != null) ? titleText.getText() : Messages.QUERY_TITLE_FALLBACK; } + + @Override + public Projects getProjects() { + return configuration.getProjects(); + } } diff --git a/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/query/RedmineRepositoryStoredQueryPage.java b/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/query/RedmineRepositoryStoredQueryPage.java index 8f5e426..3db4d92 100644 --- a/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/query/RedmineRepositoryStoredQueryPage.java +++ b/net.sf.redmine_mylyn.ui/src/net/sf/redmine_mylyn/internal/ui/query/RedmineRepositoryStoredQueryPage.java @@ -2,6 +2,7 @@ import net.sf.redmine_mylyn.api.exception.RedmineApiErrorException; import net.sf.redmine_mylyn.api.model.Configuration; +import net.sf.redmine_mylyn.api.model.container.Projects; import net.sf.redmine_mylyn.api.query.CompareOperator; import net.sf.redmine_mylyn.api.query.Query; import net.sf.redmine_mylyn.api.query.QueryField; @@ -27,7 +28,7 @@ import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; -public class RedmineRepositoryStoredQueryPage extends AbstractRedmineRepositoryQueryPage { +public class RedmineRepositoryStoredQueryPage extends AbstractRedmineRepositoryQueryPage implements ProjectProvider { private Composite pageComposite; @@ -52,7 +53,8 @@ public void createControl(Composite parent) { queryViewer = new ComboViewer(pageComposite, SWT.BORDER | SWT.READ_ONLY); queryViewer.setContentProvider(new RedmineContentProvider(Messages.CREATE_QUERY)); - queryViewer.setLabelProvider(new RedmineLabelProvider(Messages.CREATE_QUERY)); + final RedmineLabelProvider labelProvider = new RedmineLabelProvider(Messages.CREATE_QUERY, this); + queryViewer.setLabelProvider(labelProvider); queryViewer.setInput(Messages.CREATE_QUERY); queryViewer.getControl().setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL)); queryViewer.addSelectionChangedListener(new ISelectionChangedListener() { @@ -173,4 +175,9 @@ private net.sf.redmine_mylyn.api.model.Query getSelectedQuery() { } return null; } + + @Override + public Projects getProjects() { + return getConfiguration().getProjects(); + } } diff --git a/net.sf.redmine_mylyn/.gitignore b/net.sf.redmine_mylyn/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/net.sf.redmine_mylyn/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/net.sf.redmine_mylyn/.settings/org.eclipse.jdt.core.prefs b/net.sf.redmine_mylyn/.settings/org.eclipse.jdt.core.prefs index 47ea968..c537b63 100644 --- a/net.sf.redmine_mylyn/.settings/org.eclipse.jdt.core.prefs +++ b/net.sf.redmine_mylyn/.settings/org.eclipse.jdt.core.prefs @@ -1,4 +1,3 @@ -#Sun Feb 20 13:24:00 CET 2011 eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 diff --git a/net.sf.redmine_mylyn/META-INF/MANIFEST.MF b/net.sf.redmine_mylyn/META-INF/MANIFEST.MF index acfa199..fc7f45b 100644 --- a/net.sf.redmine_mylyn/META-INF/MANIFEST.MF +++ b/net.sf.redmine_mylyn/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: net.sf.redmine_mylyn;singleton:=true -Bundle-Version: 0.4.0.qualifier +Bundle-Version: 0.4.1.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-Localization: plugin diff --git a/net.sf.redmine_mylyn/pom.xml b/net.sf.redmine_mylyn/pom.xml index 2781af4..c331df5 100644 --- a/net.sf.redmine_mylyn/pom.xml +++ b/net.sf.redmine_mylyn/pom.xml @@ -6,8 +6,8 @@ net.sf.redmine_mylyn + 0.4.1-SNAPSHOT net.sf.redmine_mylyn.parent - 0.4.0-SNAPSHOT net.sf.redmine_mylyn diff --git a/pom.xml b/pom.xml index 75e0fe5..a4c2bfc 100644 --- a/pom.xml +++ b/pom.xml @@ -1,186 +1,202 @@ - - 4.0.0 + 4.0.0 - - 3.0 - + + 3.0 + - net.sf.redmine_mylyn - net.sf.redmine_mylyn.parent - 0.4.0-SNAPSHOT - pom - - - net.sf.redmine_mylyn - net.sf.redmine_mylyn.common - net.sf.redmine_mylyn.api - net.sf.redmine_mylyn.core - net.sf.redmine_mylyn.ui - - net.sf.redmine_mylyn.feature - - net.sf.redmine_mylyn.p2repository - + net.sf.redmine_mylyn + net.sf.redmine_mylyn.parent + 0.4.1-SNAPSHOT + pom - - 0.20.0 - indigo - UTF-8 - http://download.eclipse.org/releases/${platform-version-name} - http://download.eclipse.org/mylyn/releases/latest - http://download.eclipse.org/tools/orbit/downloads/drops/R20110523182458/repository/ - http://download.eclipse.org/tools/ajdt/37/dev/update - - - - - eclipse-platform - p2 - ${eclipse-site} - - - mylyn - p2 - ${mylyn-site} - - - orbit - p2 - ${orbit-site} - - - aspectj - p2 - ${aspectj-site} - - - - - src + + net.sf.redmine_mylyn + net.sf.redmine_mylyn.common + net.sf.redmine_mylyn.api + net.sf.redmine_mylyn.core + net.sf.redmine_mylyn.ui - - - org.eclipse.tycho - tycho-maven-plugin - ${tycho-version} - true - - - org.eclipse.tycho - target-platform-configuration - ${tycho-version} - - p2 - - - - - - - - org.eclipse.tycho - tycho-compiler-plugin - ${tycho-version} - - UTF-8 - - - - - org.apache.maven.plugins - maven-resources-plugin - 2.4.1 - - ISO-8859-1 - - - - - - + net.sf.redmine_mylyn.feature - - - platform-helios - - - platform-version-name - helios - - - - http://download.eclipse.org/releases/helios - [3.6,3.7) - - - - platform-indigo - - - platform-version-name - indigo - - - - http://download.eclipse.org/releases/indigo - [3.7,3.8) - - - - platform-juno - - - platform-version-name - juno - - - - http://download.eclipse.org/releases/juno - [3.8,4.3) - - - - platform-kepler - - - platform-version-name - kepler - - - - http://download.eclipse.org/releases/kepler - [4.3,4.4) - - - - platform-luna - - - platform-version-name - luna - - - - http://download.eclipse.org/releases/luna - [4.4,4.5) - - - - platform-mars - - - platform-version-name - mars - - - - http://download.eclipse.org/releases/mars - [4.5,4.6) - - - + net.sf.redmine_mylyn.p2repository + + + + 0.20.0 + indigo + UTF-8 + http://download.eclipse.org/releases/${platform-version-name} + http://download.eclipse.org/mylyn/releases/latest + http://download.eclipse.org/tools/orbit/downloads/drops/R20110523182458/repository/ + http://download.eclipse.org/tools/ajdt/37/dev/update + + + + + eclipse-platform + p2 + ${eclipse-site} + + + mylyn + p2 + ${mylyn-site} + + + orbit + p2 + ${orbit-site} + + + aspectj + p2 + ${aspectj-site} + + + + + src + + + + org.eclipse.tycho + tycho-maven-plugin + ${tycho-version} + true + + + org.eclipse.tycho + target-platform-configuration + ${tycho-version} + + p2 + + + win32 + win32 + x86 + + + linux + gtk + x86_64 + + + macosx + cocoa + x86_64 + + + + + + + + + + org.eclipse.tycho + tycho-compiler-plugin + ${tycho-version} + + UTF-8 + + + + + org.apache.maven.plugins + maven-resources-plugin + 2.4.1 + + ISO-8859-1 + + + + + + + + + + platform-helios + + + platform-version-name + helios + + + + http://download.eclipse.org/releases/helios + [3.6,3.7) + + + + platform-indigo + + + platform-version-name + indigo + + + + http://download.eclipse.org/releases/indigo + [3.7,3.8) + + + + platform-juno + + + platform-version-name + juno + + + + http://download.eclipse.org/releases/juno + [3.8,4.3) + + + + platform-kepler + + + platform-version-name + kepler + + + + http://download.eclipse.org/releases/kepler + [4.3,4.4) + + + + platform-luna + + + platform-version-name + luna + + + + http://download.eclipse.org/releases/luna + [4.4,4.5) + + + + platform-mars + + + platform-version-name + mars + + + + http://download.eclipse.org/releases/mars + [4.5,4.6) + + +