Rev 42 | Go to most recent revision | View as "text/plain" | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
/*
* Mylyn Connector for Serena Business Mashups
* Copyright 2010 Brian Rosenberger (Brutex Network)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Serena, TeamTrack and Serena Business Mashup are
* registered trademarks of SERENA Software Inc.
*/
package net.brutex.mylyn.sbmconnector.core;
import java.math.BigInteger;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import net.brutex.mylyn.sbmconnector.SBMConnectorPlugin;
import net.brutex.mylyn.sbmconnector.core.model.SBMField;
import net.brutex.mylyn.sbmconnector.core.model.SBMFieldTypes;
import net.brutex.mylyn.sbmconnector.core.model.SBMFieldValue;
import net.brutex.mylyn.sbmconnector.core.model.SBMNote;
import net.brutex.mylyn.sbmconnector.core.model.SBMStaticFields;
import net.brutex.sbm.wsclient.AEWebservicesFaultFault;
import net.brutex.sbm.wsclient.Aewebservices71;
import net.brutex.sbm.wsclient.Aewebservices71PortType;
import net.brutex.sbm.wsclient.Auth;
import net.brutex.sbm.wsclient.Field;
import net.brutex.sbm.wsclient.NameValue;
import net.brutex.sbm.wsclient.Note;
import net.brutex.sbm.wsclient.ObjectFactory;
import net.brutex.sbm.wsclient.ReportCategory;
import net.brutex.sbm.wsclient.ReportInfo;
import net.brutex.sbm.wsclient.ReportResult;
import net.brutex.sbm.wsclient.ReportsFilter;
import net.brutex.sbm.wsclient.RunReportResult;
import net.brutex.sbm.wsclient.TTItem;
import net.brutex.sbm.wsclient.TableData;
import net.brutex.sbm.wsclient.TableType;
import net.brutex.sbm.wsclient.Value;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.mylyn.commons.net.AuthenticationCredentials;
import org.eclipse.mylyn.commons.net.AuthenticationType;
import org.eclipse.mylyn.tasks.core.RepositoryStatus;
import org.eclipse.mylyn.tasks.core.TaskRepository;
public class SBMClient {
private Aewebservices71PortType port;
private static final QName SERVICE_NAME = new QName("http://localhost:80/gsoap/aewebservices71.wsdl", "aewebservices71");
private TaskRepository repository;
private ObjectFactory of;
private List<TableData> tables = new ArrayList<TableData>();
private Map<String, List<SBMFieldValue>> validsets = new HashMap<String, List<SBMFieldValue>>();
/**
* Instantiates a new SBM client.
* Creates new instance of the aewebservices71 {@link net.brutex.sbm.wsclient.ObjectFactory} and
* initializes web service endpoint from repository url.
*
* @param repository the repository
*/
public SBMClient(TaskRepository repository) {
this.repository = repository;
this.of = new ObjectFactory();
URL wsdlURL = Aewebservices71.WSDL_LOCATION;
wsdlURL = this.getClass().getResource("/META-INF/aewebservices71.wsdl");
Aewebservices71 ss = new Aewebservices71(wsdlURL, SERVICE_NAME);
port = ss.getAewebservices71();
((BindingProvider)port).getRequestContext().put(
BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
repository.getRepositoryUrl());
}
/**
* Can authenticate checks if this SBMClient instance has proper authentication details
* set in its related repository. The check is done by invoking the GetUser web service.
*
* @return true, if successful
* @throws CoreException the core exception
*/
public boolean canAuthenticate() throws CoreException {
try {
port.getUser(getAuth(), repository.getCredentials(AuthenticationType.REPOSITORY).getUserName());
} catch (AEWebservicesFaultFault e) {
new CoreException(RepositoryStatus.createLoginError(
repository.getRepositoryUrl(), SBMConnectorPlugin.PLUGIN_ID));
return false;
}
return true;
}
public List<TTItem> getTTItemsByTable(String tablename, String sql_where) throws CoreException {
return getTTItemsByTable(tablename, sql_where, false);
}
/**
* Gets the SBM items from a table. The result size is limited to 500 and the sorting is done
* by TS_ID descending.
*
* @param tablename the tablename
* @param sql_where the sql_where
* @return the tT items by table
* @throws CoreException the core exception
*/
public List<TTItem> getTTItemsByTable(String tablename, String sql_where, boolean getFullData) throws CoreException {
List<TTItem> list = new ArrayList<TTItem>();
String sections = "SECTION:FIXED";
if(getFullData) sections = "SECTION:ALL";
if(sql_where==null || sql_where.isEmpty()) sql_where = "TS_ID>0";
try {
list = port.getItemsByQueryWithName(
getAuth(),
tablename,
"("+sql_where+")",
"TS_ID desc",
null,
sections);
} catch (AEWebservicesFaultFault e) {
throw new CoreException(
RepositoryStatus.createInternalError(
SBMConnectorPlugin.PLUGIN_ID, e.getMessage(), e));
}
return list;
}
public List<TTItem> getTTItemsByReport(String reportuuid) throws CoreException {
List<TTItem> list = new ArrayList<TTItem>();
try {
RunReportResult result = port.runReport(
getAuth(), of.createQueryRange(), reportuuid, null, null, null, null, null, null,
null, null, null, null, null);
List<ReportResult> resultlist = result.getResult();
for(ReportResult r : resultlist) {
list.add(port.getItem( getAuth(), r.getItemId().getValue(), null));
}
} catch (AEWebservicesFaultFault e) {
throw new CoreException(
RepositoryStatus.createInternalError(
SBMConnectorPlugin.PLUGIN_ID, e.getMessage(), e));
}
return list;
}
public List<ReportInfo> getReportList(String solutionname) throws CoreException {
ReportsFilter filter = of.createReportsFilter();
List<ReportInfo> reportlist = new ArrayList<ReportInfo>();
filter.setSolutionName(of.createSolutionDataName(solutionname));
filter.setReportCategory(ReportCategory.USERREPORTS); //Limit this for now, because we execute by uuid only
try {
reportlist = port.getReports(getAuth(), null, filter).getReport();
} catch (AEWebservicesFaultFault e) {
throw new CoreException(
RepositoryStatus.createInternalError(
SBMConnectorPlugin.PLUGIN_ID, e.getMessage(), e));
}
return reportlist;
}
public List<String> getResultCount(String tablename, String sql) throws CoreException {
List<TTItem> list = new ArrayList<TTItem>();
List<String> idlist = new ArrayList<String>();
try {
list = port.getItemsByQueryWithName(
getAuth(),
tablename,
"("+sql+")",
"TS_ID desc",
null,
"SECTION:NONE");
} catch (AEWebservicesFaultFault e) {
throw new CoreException(
RepositoryStatus.createInternalError(
SBMConnectorPlugin.PLUGIN_ID, e.getMessage(), e));
}
for (TTItem item : list) {
idlist.add(item.getGenericItem().getValue().getItemID().getValue());
}
return idlist;
}
/**
* Gets a SBM item specified by its internal identifier ([tableid:recordid])
*
* @param itemid the itemid
* @return the tT item
*/
public TTItem getTTItem(String itemid) {
int pos1;
int pos2;
pos1 = itemid.lastIndexOf("[")+1;
pos2 = itemid.lastIndexOf("]");
itemid = itemid.substring(pos1, pos2);
TTItem item = of.createTTItem();
try {
item = port.getItem(getAuth(), itemid, null);
} catch (AEWebservicesFaultFault e) {
new CoreException(
RepositoryStatus.createInternalError(
SBMConnectorPlugin.PLUGIN_ID, e.getFaultInfo(), e));
}
return item;
}
private Auth getAuth() {
Auth auth = of.createAuth();
AuthenticationCredentials credentials = repository.getCredentials(AuthenticationType.REPOSITORY);
auth.setUserId(of.createAuthUserId(credentials.getUserName()));
auth.setPassword(of.createAuthPassword(credentials.getPassword()));
return auth;
}
/**
* Gets the field value for a system generic field.
*
* @param ttitem the ttitem
* @param fieldname the fieldname
* @return the static field value
*/
public String getStaticFieldValue(TTItem ttitem, String fieldname) {
if(fieldname.equals(SBMStaticFields.SUBMITDATE.getValue())) {
Date date = ttitem.getCreateDate().getValue().toGregorianCalendar().getTime();
return String.valueOf(date.getTime());
}
if(fieldname.equals(SBMStaticFields.LASTMODIFIEDDATE.getValue())) {
return String.valueOf(ttitem.getModifiedDate().getValue().toGregorianCalendar().getTimeInMillis());
}
if(fieldname.equals("TITLE")) {
if(ttitem.getTitle()==null || ttitem.getTitle().isNil()) return "";
return ttitem.getTitle().getValue();
}
if(fieldname.equals(SBMStaticFields.ISSUEID.getValue())) {
if(ttitem.getGenericItem()==null || ttitem.getGenericItem().getValue().getItemName()==null) {
return "";
}
return ttitem.getGenericItem().getValue().getItemName().getValue();
}
if(fieldname.equals("ISSUETYPE")) {
if(ttitem.getItemType()==null || ttitem.getItemType().isNil()) return "";
return ttitem.getItemType().getValue();
}
if(fieldname.equals(SBMStaticFields.STATE.getValue())) {
if(ttitem.getState()==null || ttitem.getState().isNil()) return "";
return ttitem.getState().getValue();
}
if(fieldname.equals(SBMStaticFields.ID.getValue())) {
return ttitem.getGenericItem().getValue().getItemName().getValue()+
" ["+ttitem.getGenericItem().getValue().getItemID().getValue()+"]";
}
if(fieldname.equals(SBMStaticFields.PROJECTID.getValue())) {
if(ttitem.getClassification() ==null || ttitem.getClassification().isNil()) return "";
return ttitem.getClassification().getValue();
}
if(fieldname.equals(SBMStaticFields.PROJECTUUID.getValue())) {
if(ttitem.getClassificationUUID()==null || ttitem.getClassificationUUID().isNil()) return "";
return ttitem.getClassificationUUID().getValue();
}
if(fieldname.equals("DESCRIPTION")) {
if(ttitem.getDescription() == null || ttitem.getDescription().isNil()) return "";
return ttitem.getDescription().getValue();
}
if(fieldname.equals(SBMStaticFields.SUBMITTER.getValue())) {
if(ttitem.getCreatedBy()==null || ttitem.getCreatedBy().isNil()) return "";
return ttitem.getCreatedBy().getValue();
}
if(fieldname.equals(SBMStaticFields.SUBMITDATE.getValue())) {
return String.valueOf(ttitem.getCreateDate().getValue().toGregorianCalendar().getTimeInMillis());
}
if(fieldname.equals(SBMStaticFields.LASTMODIFIER.getValue())) {
if(ttitem.getModifiedBy()==null || ttitem.getModifiedBy().isNil()) return "";
return ttitem.getModifiedBy().getValue();
}
if(fieldname.equals(SBMStaticFields.LASTMODIFIEDDATE.getValue())) {
return String.valueOf(ttitem.getModifiedDate().getValue().toGregorianCalendar().getTimeInMillis());
}
if(fieldname.equals(SBMStaticFields.ACTIVEINACTIVE.getValue())) {
return ttitem.getActiveInactive().getValue();
}
if(fieldname.equals(SBMStaticFields.OWNER.getValue())) {
return ttitem.getOwner().getValue();
}
if(fieldname.equals(SBMStaticFields.ITEMURL.getValue())) {
return ttitem.getUrl().getValue();
}
if(fieldname.equals(SBMStaticFields.UUID.getValue())) {
return ttitem.getGenericItem().getValue().getItemUUID().getValue();
}
if(fieldname.equals(SBMStaticFields.CLOSEDATE.getValue())) {
Iterator<NameValue> list = ttitem.getExtendedFieldList().iterator();
while (list.hasNext()) {
NameValue field = list.next();
if(field.getName().getValue().equals("CLOSEDATE")) {
return field.getValue().getValue().getInternalValue().getValue();
}
}
}
if(fieldname.equals(SBMStaticFields.LASTSTATECHANGEDATE.getValue())) {
Iterator<NameValue> list = ttitem.getExtendedFieldList().iterator();
while (list.hasNext()) {
NameValue field = list.next();
if(field.getName().getValue().equals("LASTSTATECHANGEDATE")) {
return field.getValue().getValue().getInternalValue().getValue();
}
}
}
if(fieldname.equals(SBMStaticFields.SECONDARYOWNER.getValue())) {
Iterator<NameValue> list = ttitem.getExtendedFieldList().iterator();
while (list.hasNext()) {
NameValue field = list.next();
if(field.getName().getValue().equals("SECONDARYOWNER")) {
return field.getValue().getValue().getInternalValue().getValue();
}
}
}
if(fieldname.equals(SBMStaticFields.LASTSTATECHANGER.getValue())) {
Iterator<NameValue> list = ttitem.getExtendedFieldList().iterator();
while (list.hasNext()) {
NameValue field = list.next();
if(field.getName().getValue().equals("LASTSTATECHANGER")) {
return field.getValue().getValue().getDisplayValue().getValue();
}
}
}
return "UNKNOWN";
}
/**
* Gets the field label. The SBM item is used to determine the table id of
* the table where this field is in.
*
* @param ttitem the ttitem
* @param fieldname the fieldname
* @return the field label
*/
public String getFieldLabel(TTItem ttitem, String fieldname) {
refreshTables();
String itemid = ttitem.getGenericItem().getValue().getItemID().getValue();
String tableid = new StringTokenizer(itemid, ":").nextToken();
for (TableData table : tables) {
if (String.valueOf(table.getTableID().intValue()).equals(tableid)) {
Iterator<Field> iter = table.getFieldList().iterator();
while(iter.hasNext()) {
Field f = iter.next();
if(f.getName().getValue().equals(fieldname)) {
return f.getDisplayName().getValue();
}
}
break;
}
}
return fieldname; //field has not been found
}
/**
* Gets the table database name.
*
* @param ttitem the ttitem
* @return the table name or null in case table is not found
*/
public String getTableName(TTItem ttitem) {
refreshTables();
String itemid = ttitem.getGenericItem().getValue().getItemID().getValue();
String tableid = new StringTokenizer(itemid, ":").nextToken();
for (TableData table : tables) {
if (String.valueOf(table.getTableID().intValue()).equals(tableid)) {
return table.getName().getValue();
}
}
return null;
}
/**
* Gets the notes attached to a SBM item.
*
* @param ttitem the ttitem
* @return the notes
*/
public List<SBMNote> getNotes(TTItem ttitem) {
List<SBMNote> notes = new ArrayList<SBMNote>();
Iterator<Note> iter = ttitem.getNoteList().iterator();
while(iter.hasNext()) {
Note n = iter.next();
SBMNote note = new SBMNote("sbm_user",
n.getTitle().getValue()+"\n"+n.getNote().getValue(),
n.getModificationDateTime().toGregorianCalendar().getTime(),
n.getId().toString());
notes.add(note);
}
return notes;
}
/**
* Gets the names of all available primary tables.
* A table name is a unique reference within one SBM environment, thus can be
* used as a key.
*
* @return the primary table names as a list
*/
public List<String> getPrimaryTables() {
refreshTables();
List<String> table_names = new ArrayList<String>();
for (TableData table : tables) {
table_names.add(table.getName().getValue());
}
return table_names;
}
/**
* Refresh table specifications from SBM web service. This
* is only done once per SBMClient instance.
*/
private void refreshTables() {
if (tables.isEmpty()) {
try {
//currently we limit this to primary tables
tables = port.getTables(getAuth(), null, TableType.PRIMARY_TABLE);
} catch (AEWebservicesFaultFault e) {
new CoreException(
RepositoryStatus.createInternalError(
SBMConnectorPlugin.PLUGIN_ID, e.getFaultInfo(), e));
}
}
}
/**
* Gets the fields for a primary table
*
* @param tablename the table database name
* @return the fields, empty when table does not exist
*/
public List<SBMField> getFields(String tablename) {
refreshTables();
List<SBMField> fields = new ArrayList<SBMField>();
for (TableData table : tables) {
if(table.getName().getValue().equals(tablename)) {
Iterator<Field> iter = table.getFieldList().iterator();
while(iter.hasNext()) {
Field f = iter.next();
SBMField nf = new SBMField(
SBMFieldTypes.fromValue(f.getFieldType().value()),
tablename,
f.getDisplayName().getValue(),
f.getName().getValue());
fields.add(nf);
}
break;
}
}
return fields;
}
/**
* Gets the field value for custom defined field.
* (those from <extendedFieldList>)
*
* @param ttitem the ttitem
* @param fieldname the fieldname
* @return the field value or null if the field is not found
*/
public SBMFieldValue getFieldValue(TTItem ttitem, String fieldname) {
SBMFieldValue value;
Iterator<NameValue> fs = ttitem.getExtendedFieldList().iterator();
while(fs.hasNext()) {
NameValue nv = fs.next();
if(nv.getName().getValue().equals(fieldname)) {
if (nv.getValue()!=null && !nv.getValue().isNil()) {
value = new SBMFieldValue(
nv.getValue().getValue().getInternalValue().getValue(),
nv.getValue().getValue().getDisplayValue().getValue());
return value;
}
}
}
return null;
}
/**
* Gets the field values for custom defined, multi type field.
* (those from <extendedFieldList>)
*
* @param ttitem the ttitem
* @param fieldname the fieldname
* @return the list of field values
*/
public List<SBMFieldValue> getFieldValues(TTItem ttitem, String fieldname) {
List<SBMFieldValue> values = new ArrayList<SBMFieldValue>();
Iterator<NameValue> fs = ttitem.getExtendedFieldList().iterator();
while(fs.hasNext()) {
NameValue nv = fs.next();
if(nv.getName().getValue().equals(fieldname)) {
if (nv.getValues()!=null && !nv.getValues().isEmpty()) {
Iterator<Value> nvv = nv.getValues().iterator();
while(nvv.hasNext()) {
Value nvv_value = nvv.next();
SBMFieldValue value = new SBMFieldValue(
nvv_value.getInternalValue().getValue(),
nvv_value.getDisplayValue().getValue());
values.add(value);
}
return values;
}
}
}
return values;
}
public List<SBMFieldValue> getValidSet(String tablename, String fieldname) {
if(validsets.containsKey(tablename+":"+fieldname)) return validsets.get(tablename+":"+fieldname);
List<SBMFieldValue> list = new ArrayList<SBMFieldValue>();
List<TTItem> ttlist = new ArrayList<TTItem>();
String sql = "TS_ID in (select max(TS_ID) from "+tablename+" group by ts_"+fieldname+")";
try {
ttlist = getTTItemsByTable(tablename, sql);
} catch (CoreException e) {
new CoreException(
RepositoryStatus.createInternalError(
SBMConnectorPlugin.PLUGIN_ID, e.getMessage(), e));
}
for(TTItem ttitem : ttlist) {
list.add(getFieldValue(ttitem, fieldname));
}
validsets.put(tablename+":"+fieldname, list);
return list;
}
}