+ wx.GetApp().GetTopWindow())
+ return False
+
+
+ def MoveFile(self, file, newFolderPath):
+ return self.MoveFiles([file], newFolderPath)
+
+
+ def MoveFiles(self, files, newFolderPath):
+ filePaths = []
+ isArray = isinstance(newFolderPath, type([]))
+ for i in range(len(files)):
+ if isArray:
+ files[i].logicalFolder = newFolderPath[i]
+ else:
+ files[i].logicalFolder = newFolderPath
+ filePaths.append(files[i].filePath)
+
+ self.UpdateAllViews(hint = ("remove", self, filePaths))
+ self.UpdateAllViews(hint = ("add", self, filePaths, []))
+ self.Modify(True)
+ return True
+
+
+ def UpdateFilePath(self, oldFilePath, newFilePath):
+ file = self.GetModel().FindFile(oldFilePath)
+ self.RemoveFile(oldFilePath)
+ if file:
+ self.AddFile(newFilePath, file.logicalFolder, file.type, file.name)
+ else:
+ self.AddFile(newFilePath)
+
+
+ def RemoveInvalidPaths(self):
+ """Makes sure all paths project knows about are valid and point to existing files. Removes and returns list of invalid paths."""
+
+ invalidFileRefs = []
+
+ fileRefs = self.GetFileRefs()
+
+ for fileRef in fileRefs:
+ if not os.path.exists(fileRef.filePath):
+ invalidFileRefs.append(fileRef)
+
+ for fileRef in invalidFileRefs:
+ fileRefs.remove(fileRef)
+
+ return [fileRef.filePath for fileRef in invalidFileRefs]
+
+
+ def SetStageProjectFile(self):
+ self._stageProjectFile = True
+
+
+ def ArchiveProject(self, zipdest, stagedir):
+ """Zips stagedir, creates a zipfile that has as name the projectname, in zipdest. Returns path to zipfile."""
+ if os.path.exists(zipdest):
+ raise AssertionError("Cannot archive project, %s already exists" % zipdest)
+ fileutils.zip(zipdest, stagedir)
+
+ return zipdest
+
+
+ def StageProject(self, tmpdir, targetDataSourceMapping={}):
+ """ Copies all files this project knows about into staging location. Files that live outside of the project dir are copied into the root of the stage dir, and their recorded file path is updated. Files that live inside of the project dir keep their relative path. Generates .dpl file into staging dir. Returns path to staging dir."""
+
+ projname = self.GetProjectName()
+ stagedir = os.path.join(tmpdir, projname)
+ fileutils.remove(stagedir)
+ os.makedirs(stagedir)
+
+ # remove invalid files from project
+ self.RemoveInvalidPaths()
+
+ # required so relative paths are written correctly when .dpl file is
+ # generated below.
+ self.SetFilename(os.path.join(stagedir,
+ os.path.basename(self.GetFilename())))
+ projectdir = self.GetModel().homeDir
+
+ # Validate paths before actually copying, and populate a dict
+ # with src->dest so copying is easy.
+ # (fileDict: ProjectFile instance -> dest path (string))
+ fileDict = self._ValidateFilePaths(projectdir, stagedir)
+
+ # copy files to staging dir
+ self._StageFiles(fileDict)
+
+ # set target data source for schemas
+ self._SetSchemaTargetDataSource(fileDict, targetDataSourceMapping)
+
+ # it is unfortunate we require this. it would be nice if filepaths
+ # were only in the project
+ self._FixWsdlAgFiles(stagedir)
+
+ # generate .dpl file
+ dplfilename = projname + deploymentlib.DEPLOYMENT_EXTENSION
+ dplfilepath = os.path.join(stagedir, dplfilename)
+ self.GenerateDeployment(dplfilepath)
+
+ if self._stageProjectFile:
+ # save project so we get the .agp file. not required for deployment
+ # but convenient if user wants to open the deployment in the IDE
+ agpfilename = projname + PROJECT_EXTENSION
+ agpfilepath = os.path.join(stagedir, agpfilename)
+
+ # if this project has deployment data sources configured, remove
+ # them. changing the project is fine, since this is a clone of
+ # the project the IDE has.
+ self.GetModel().GetAppInfo().ResetDeploymentDataSources()
+
+ f = None
+ try:
+ f = open(agpfilepath, "w")
+
+ # setting homeDir correctly is required for the "figuring out
+ # relative paths" logic when saving the project
+ self.GetModel().homeDir = stagedir
+
+ projectlib.save(f, self.GetModel(), productionDeployment=True)
+ finally:
+ try:
+ f.close()
+ except: pass
+
+ return stagedir
+
+ def _FixWsdlAgFiles(self, stagedir):
+ """For each wsdlag file in the stagedir: if referenced artifact (wsdl or code file) is a known product file (such as securityservice.wsdl), make sure patch to it is parameterized with special env var. We do not want to copy those files. For user artifacts, ensure the file lives in root of stagedir. This should be the case if it is part of project (since staging has run). If it is not at root of stagedir, copy it. Then update path in wsdlag."""
+ files = os.listdir(stagedir)
+ for f in files:
+ if (f.endswith(WsdlAgEditor.WsdlAgDocument.WSDL_AG_EXT)):
+ wsdlagpath = os.path.join(stagedir, f)
+ fileObject = None
+ modified = False
+ try:
+ fileObject = open(wsdlagpath)
+ serviceref = WsdlAgEditor.load(fileObject)
+
+ # referenced wsdl
+ if (hasattr(serviceref, WsdlAgModel.WSDL_FILE_ATTR)):
+ modified = (modified |
+ self._UpdateServiceRefPathAttr(
+ stagedir, serviceref,
+ WsdlAgModel.WSDL_FILE_ATTR))
+
+ # referenced code file
+ if (hasattr(serviceref, WsdlAgModel.LOCAL_SERVICE_ELEMENT)):
+ lse = getattr(serviceref,
+ WsdlAgModel.LOCAL_SERVICE_ELEMENT)
+ if (hasattr(lse, WsdlAgModel.LOCAL_SERVICE_FILE_ATTR)):
+ modified = (modified |
+ self._UpdateServiceRefPathAttr(
+ stagedir, lse,
+ WsdlAgModel.LOCAL_SERVICE_FILE_ATTR))
+
+
+ finally:
+ try:
+ fileObject.close()
+ except:
+ pass
+
+ # no need to save the file if we did not change anything
+ if not modified: continue
+
+ # write the wsdlag file
+ fileObject = open(wsdlagpath)
+ try:
+ serviceref = WsdlAgEditor.save(fileObject, serviceref)
+ finally:
+ try:
+ fileObject.close()
+ except:
+ pass
+
+
+ def _UpdateServiceRefPathAttr(self, stagedir, serviceref, attrName):
+ """Returns True if serviceref path has been updated, False otherwise."""
+
+ filePath = getattr(serviceref, attrName)
+
+ if (filePath == None):