1 37 package net.sourceforge.cruisecontrol.publishers.sfee; 38 39 import com.vasoftware.sf.soap42.webservices.ClientSoapStubFactory; 40 import com.vasoftware.sf.soap42.webservices.docman.DocumentFolderSoapDO; 41 import com.vasoftware.sf.soap42.webservices.docman.DocumentFolderSoapList; 42 import com.vasoftware.sf.soap42.webservices.docman.DocumentFolderSoapRow; 43 import com.vasoftware.sf.soap42.webservices.docman.DocumentSoapDO; 44 import com.vasoftware.sf.soap42.webservices.docman.DocumentSoapList; 45 import com.vasoftware.sf.soap42.webservices.docman.DocumentSoapRow; 46 import com.vasoftware.sf.soap42.webservices.docman.IDocumentAppSoap; 47 import com.vasoftware.sf.soap42.webservices.filestorage.IFileStorageAppSoap; 48 import com.vasoftware.sf.soap42.webservices.sfmain.ISourceForgeSoap; 49 import net.sourceforge.cruisecontrol.CruiseControlException; 50 import net.sourceforge.cruisecontrol.util.ValidationHelper; 51 import net.sourceforge.cruisecontrol.util.XPathAwareChild; 52 import org.jdom.Element; 53 54 import javax.activation.DataHandler ; 55 import javax.activation.DataSource ; 56 import javax.activation.FileDataSource ; 57 import java.rmi.RemoteException ; 58 import java.util.StringTokenizer ; 59 60 64 public class SfeeDocumentManagerPublisher extends SfeePublisher { 65 66 private String projectName; 67 private XPathAwareChild documentName; 68 private XPathAwareChild description; 69 private DataSource dataSrc; 70 private String path; 71 private Status status; 72 private XPathAwareChild versionComment; 73 private boolean lock; 74 private String documentPath; 75 76 public Status createStatus() { 77 status = new Status(); 78 return status; 79 } 80 81 public XPathAwareChild createVersionComment() { 82 versionComment = new XPathAwareChild(); 83 return versionComment; 84 } 85 86 public void setLock(boolean lock) { 87 this.lock = lock; 88 } 89 90 public void setData(DataSource dataSrc) { 91 this.dataSrc = dataSrc; 92 } 93 94 public XPathAwareChild createDocumentName() { 95 documentName = new XPathAwareChild(); 96 return documentName; 97 } 98 99 public XPathAwareChild createDescription() { 100 description = new XPathAwareChild(); 101 return description; 102 } 103 104 public void setProjectName(String name) { 105 projectName = name; 106 } 107 108 public void setFolder(String path) { 109 this.path = path; 110 } 111 112 public void publish(Element cruisecontrolLog) throws CruiseControlException { 113 114 ISourceForgeSoap sfee = (ISourceForgeSoap) ClientSoapStubFactory 115 .getSoapStub(ISourceForgeSoap.class, getServerURL()); 116 String sessionID; 117 try { 118 sessionID = sfee.login(getUsername(), getPassword()); 119 } catch (RemoteException e) { 120 throw new CruiseControlException(e); 121 } 122 123 IFileStorageAppSoap fileStorage = (IFileStorageAppSoap) ClientSoapStubFactory 124 .getSoapStub(IFileStorageAppSoap.class, getServerURL()); 125 String fileID; 126 String mimeType; 127 try { 128 if (documentPath != null) { 129 dataSrc = new FileDataSource (documentPath); 130 } 131 DataHandler dataHandler = new DataHandler (dataSrc); 132 fileID = fileStorage.uploadFile(sessionID, dataHandler); 133 mimeType = dataHandler.getContentType(); 134 } catch (RemoteException e) { 135 throw new CruiseControlException(e); 136 } 137 138 DocumentFolderSoapDO folder = findFolder(path); 139 String intendedDocumentName = 140 (documentName != null ? documentName.lookupValue(cruisecontrolLog) : dataSrc.getName()); 141 String intendedVersionComment = 142 (versionComment != null ? versionComment.lookupValue(cruisecontrolLog) : null); 143 144 DocumentSoapDO existingDocument; 145 try { 146 existingDocument = findExistingDocument(sessionID, folder, intendedDocumentName); 147 } catch (RemoteException e) { 148 throw new CruiseControlException(e); 149 } 150 151 if (existingDocument != null) { 152 updateExistingDocument(sessionID, existingDocument, intendedVersionComment, mimeType, fileID, 153 cruisecontrolLog); 154 } else { 155 createNewDocument(cruisecontrolLog, sessionID, intendedDocumentName, intendedVersionComment, folder, 156 mimeType, fileID); 157 } 158 } 159 160 private void updateExistingDocument(String sessionID, DocumentSoapDO existingDocument, String versionComment, 161 String mimeType, 162 String fileID, Element cruiseControlLog) throws CruiseControlException { 163 IDocumentAppSoap docApp = (IDocumentAppSoap) ClientSoapStubFactory 164 .getSoapStub(IDocumentAppSoap.class, getServerURL()); 165 existingDocument.setDescription(description.lookupValue(cruiseControlLog)); 166 existingDocument.setStatus(status.lookupValue(cruiseControlLog)); 167 if (lock) { 168 existingDocument.setLockedBy(getUsername()); 169 } else { 170 existingDocument.setLockedBy(null); 171 } 172 existingDocument.setMimeType(mimeType); 173 existingDocument.setVersionComment(versionComment); 174 175 try { 176 docApp.setDocumentData(sessionID, existingDocument, fileID); 177 } catch (RemoteException e) { 178 throw new CruiseControlException(e); 179 } 180 } 181 182 private DocumentSoapDO findExistingDocument(String sessionID, DocumentFolderSoapDO folder, 183 String intendedDocumentName) 184 throws RemoteException { 185 IDocumentAppSoap docApp = (IDocumentAppSoap) ClientSoapStubFactory 186 .getSoapStub(IDocumentAppSoap.class, getServerURL()); 187 DocumentSoapList documentList = docApp.getDocumentList(sessionID, folder.getId(), null); 188 DocumentSoapRow[] existingDocuments = documentList.getDataRows(); 189 for (int i = 0; i < existingDocuments.length; i++) { 190 DocumentSoapRow existingDocument = existingDocuments[i]; 191 if (existingDocument.getTitle().equals(intendedDocumentName)) { 192 return docApp 193 .getDocumentData(sessionID, existingDocument.getId(), existingDocument.getCurrentVersion()); 194 } 195 } 196 return null; 197 } 198 199 private void createNewDocument(Element cruisecontrolLog, String sessionID, String intendedDocumentName, 200 String intendedVersionComment, DocumentFolderSoapDO folder, String mimeType, 201 String fileID) throws 202 CruiseControlException { 203 IDocumentAppSoap docApp = (IDocumentAppSoap) ClientSoapStubFactory 204 .getSoapStub(IDocumentAppSoap.class, getServerURL()); 205 try { 206 docApp.createDocument(sessionID, folder.getId(), intendedDocumentName, 207 description.lookupValue(cruisecontrolLog), intendedVersionComment, 208 status.lookupValue(cruisecontrolLog), lock, intendedDocumentName, mimeType, 209 fileID); 210 } catch (RemoteException e) { 211 throw new CruiseControlException(e); 212 } 213 } 214 215 public void subValidate() throws CruiseControlException { 216 ValidationHelper.assertIsSet(path, "folder", SfeeDocumentManagerPublisher.class); 217 ValidationHelper.assertIsSet(projectName, "projectName", SfeeDocumentManagerPublisher.class); 218 if (documentPath == null && dataSrc == null) { 219 throw new CruiseControlException("Either a document or a datasource must be specified."); 220 } 221 ValidationHelper.assertHasChild(description, "description", SfeeDocumentManagerPublisher.class); 222 description.validate(); 223 ValidationHelper.assertHasChild(status, "status", SfeeDocumentManagerPublisher.class); 224 status.validate(); 225 if (documentName != null) { 226 documentName.validate(); 227 } 228 if (versionComment != null) { 229 versionComment.validate(); 230 } 231 } 232 233 DocumentFolderSoapDO findFolder(String path) throws CruiseControlException { 234 if (path == null) { 235 throw new IllegalArgumentException ("path can not be null."); 236 } 237 238 StringTokenizer tokens = new StringTokenizer (path, "/"); 239 240 DocumentFolderSoapDO folder; 241 try { 242 ISourceForgeSoap soap = (ISourceForgeSoap) ClientSoapStubFactory 243 .getSoapStub(ISourceForgeSoap.class, getServerURL()); 244 String sessionID = soap.login(getUsername(), getPassword()); 245 String projectID = SfeeUtils.findProjectID(soap, sessionID, projectName); 246 247 IDocumentAppSoap docApp = (IDocumentAppSoap) ClientSoapStubFactory 248 .getSoapStub(IDocumentAppSoap.class, getServerURL()); 249 250 folder = findFolderInternal(sessionID, projectID, tokens, docApp); 251 252 } catch (RemoteException e) { 253 throw new CruiseControlException(e); 254 } 255 256 if (folder == null) { 257 throw new CruiseControlException("Unable to find a folder for the path specified [" + path + "]."); 258 } 259 260 return folder; 261 } 262 263 268 private static DocumentFolderSoapDO findFolderInternal(String sessionID, String parentID, 269 StringTokenizer pathTokens, IDocumentAppSoap docApp) 270 throws RemoteException { 271 272 if (!pathTokens.hasMoreTokens()) { 273 return null; 274 } 275 276 DocumentFolderSoapList folderList = docApp.getDocumentFolderList(sessionID, parentID, false); 277 DocumentFolderSoapRow[] folders = folderList.getDataRows(); 278 String nextPathElement = pathTokens.nextToken(); 279 boolean isFinalPathElement = !pathTokens.hasMoreTokens(); 280 281 for (int i = 0; i < folders.length; i++) { 282 DocumentFolderSoapRow nextFolder = folders[i]; 283 String nextFolderTitle = nextFolder.getTitle(); 284 boolean folderNamesMatch = nextFolderTitle.equals(nextPathElement); 285 if (folderNamesMatch && isFinalPathElement) { 286 return docApp.getDocumentFolderData(sessionID, nextFolder.getId()); 287 } else if (folderNamesMatch) { 288 return findFolderInternal(sessionID, nextFolder.getId(), pathTokens, docApp); 289 } 290 } 291 292 return null; 293 } 294 295 public void setDocument(String documentPath) { 296 this.documentPath = documentPath; 297 } 298 299 300 public static class Status extends XPathAwareChild { 301 public void validate() throws CruiseControlException { 302 303 if (getXpathExpression() == null && getFixedValue() != null 304 && !(getFixedValue().equalsIgnoreCase("final") || getFixedValue().equalsIgnoreCase("draft"))) { 305 throw new CruiseControlException( 306 "Status value specified [] is not valid. Valid values are 'final' and 'draft'."); 307 } 308 309 super.validate(); 310 } 311 } 312 } 313 | Popular Tags |