1 #----------------------------------------------------------------------------
3 # Purpose: project model for wx.lib.pydocview
9 # Copyright: (c) 2005 ActiveGrid, Inc.
10 # License: wxWindows License
11 #----------------------------------------------------------------------------
16 import activegrid
.util
.xmlutils
as xmlutils
17 from IDE
import ACTIVEGRID_BASE_IDE
18 if not ACTIVEGRID_BASE_IDE
:
19 import activegrid
.model
.basedocmgr
as basedocmgr
22 #----------------------------------------------------------------------------
24 #----------------------------------------------------------------------------
25 # Always add new versions, never edit the version number
26 # This allows you to upgrade the file by checking the version number
27 PROJECT_VERSION_050730
= '10'
28 PROJECT_VERSION_050826
= '11'
31 #----------------------------------------------------------------------------
32 # XML Marshalling Methods
33 #----------------------------------------------------------------------------
36 version
= xmlutils
.getAgVersion(fileObject
.name
)
37 # most current versions on top
38 if version
== PROJECT_VERSION_050826
:
40 if ACTIVEGRID_BASE_IDE
:
41 KNOWNTYPES
= {"ag:project" : Project, "ag:file" : ProjectFile}
43 KNOWNTYPES
= {"ag:project" : Project, "ag:file" : ProjectFile, "ag:appInfo" : AppInfo.AppInfo}
44 project
= xmlutils
.load(fileObject
.name
, knownTypes
=KNOWNTYPES
, knownNamespaces
=xmlutils
.KNOWN_NAMESPACES
)
45 elif version
== PROJECT_VERSION_050730
:
47 project
= xmlutils
.load(fileObject
.name
, knownTypes
={"project" : Project_10}
)
48 project
= project
.upgradeVersion()
50 # assume it is old version without version number
52 project
= xmlutils
.load(fileObject
.name
, knownTypes
={"project" : Project_10}
)
54 project
= project
.upgradeVersion()
56 print "Project, unknown version:", version
60 project
._projectDir
= os
.path
.dirname(fileObject
.name
)
61 project
.RelativeToAbsPath()
66 def save(fileObject
, project
, productionDeployment
=False):
67 if not project
._projectDir
:
68 project
._projectDir
= os
.path
.dirname(fileObject
.name
)
69 project
.AbsToRelativePath() # temporarily change it to relative paths for saving
70 if ACTIVEGRID_BASE_IDE
:
71 KNOWNTYPES
= {"ag:project" : Project, "ag:file" : ProjectFile}
73 KNOWNTYPES
= {"ag:project" : Project, "ag:file" : ProjectFile, "ag:appInfo" : AppInfo.AppInfo}
75 savedHomeDir
= project
.homeDir
76 if productionDeployment
:
77 # for deployments, we don't want an abs path in homeDir since that
78 # would tie the app to the current filesystem. So unset it.
79 project
.homeDir
= None
81 xmlutils
.save(fileObject
.name
, project
, prettyPrint
=True, knownTypes
=KNOWNTYPES
, knownNamespaces
=xmlutils
.KNOWN_NAMESPACES
)
83 if productionDeployment
:
84 project
.homeDir
= savedHomeDir
86 project
.RelativeToAbsPath() # swap it back to absolute path
89 #----------------------------------------------------------------------------
91 #----------------------------------------------------------------------------
93 class BaseProject(object):
95 __xmlname__
= "project"
96 __xmlexclude__
= ('fileName', '_projectDir', '_getDocCallback')
97 __xmlattributes__
= ("_homeDir", "version")
98 __xmlrename__
= { "_homeDir":"homeDir", "_appInfo":"appInfo" }
99 __xmlflattensequence__
= { "_files":("file",) }
100 __xmldefaultnamespace__
= xmlutils
.AG_NS_URL
101 __xmlattrnamespaces__
= { "ag": ["version", "_homeDir"] }
105 self
.__xmlnamespaces
__ = { "ag" : xmlutils.AG_NS_URL }
106 self
.version
= PROJECT_VERSION_050826
108 self
._projectDir
= None # default for homeDir, set on load
109 self
._homeDir
= None # user set homeDir for use in calculating relative path
110 if not ACTIVEGRID_BASE_IDE
:
111 self
._appInfo
= AppInfo
.AppInfo()
116 clone
._files
= [copy
.copy(file) for file in self
._files
]
117 clone
._projectDir
= self
._projectDir
118 clone
._homeDir
= self
._homeDir
119 if not ACTIVEGRID_BASE_IDE
:
120 clone
._appInfo
= self
._appInfo
124 def initialize(self
):
125 """ Required method for xmlmarshaller """
129 def GetAppInfo(self
):
133 def AddFile(self
, filePath
=None, logicalFolder
=None, type=None, name
=None, file=None):
134 """ Usage: self.AddFile(filePath, logicalFolder, type, name) # used for initial generation of object
135 self.AddFile(file=xyzFile) # normally used for redo/undo
136 Add newly created file object using filePath and logicalFolder or given file object
139 self
._files
.append(file)
141 self
._files
.append(ProjectFile(filePath
, logicalFolder
, type, name
, getDocCallback
=self
._getDocCallback
))
144 def RemoveFile(self
, file):
145 self
._files
.remove(file)
148 def FindFile(self
, filePath
):
150 for file in self
._files
:
151 if file.filePath
== filePath
:
157 def _GetFilePaths(self
):
158 return [file.filePath
for file in self
._files
]
161 filePaths
= property(_GetFilePaths
)
164 def _GetLogicalFolders(self
):
166 for file in self
._files
:
167 if file.logicalFolder
and file.logicalFolder
not in folders
:
168 folders
.append(file.logicalFolder
)
172 logicalFolders
= property(_GetLogicalFolders
)
175 def _GetPhysicalFolders(self
):
177 for file in self
._files
:
178 physicalFolder
= file.physicalFolder
179 if physicalFolder
and physicalFolder
not in physicalFolders
:
180 physicalFolders
.append(physicalFolder
)
181 return physicalFolders
184 physicalFolders
= property(_GetPhysicalFolders
)
187 def _GetHomeDir(self
):
191 return self
._projectDir
194 def _SetHomeDir(self
, parentPath
):
195 self
._homeDir
= parentPath
198 def _IsDefaultHomeDir(self
):
199 return (self
._homeDir
== None)
202 isDefaultHomeDir
= property(_IsDefaultHomeDir
)
205 homeDir
= property(_GetHomeDir
, _SetHomeDir
)
208 def GetRelativeFolders(self
):
210 for file in self
._files
:
211 relFolder
= file.GetRelativeFolder(self
.homeDir
)
212 if relFolder
and relFolder
not in relativeFolders
:
213 relativeFolders
.append(relFolder
)
214 return relativeFolders
217 def AbsToRelativePath(self
):
218 for file in self
._files
:
219 file.AbsToRelativePath(self
.homeDir
)
222 def RelativeToAbsPath(self
):
223 for file in self
._files
:
224 file.RelativeToAbsPath(self
.homeDir
)
227 #----------------------------------------------------------------------------
228 # BaseDocumentMgr methods
229 #----------------------------------------------------------------------------
232 def fullPath(self
, fileName
):
233 fileName
= super(BaseProject
, self
).fullPath(fileName
)
235 if os
.path
.isabs(fileName
):
238 absPath
= os
.path
.join(self
.homeDir
, fileName
)
240 absPath
= os
.path
.abspath(fileName
)
241 return os
.path
.normpath(absPath
)
244 def documentRefFactory(self
, name
, fileType
, filePath
):
245 return ProjectFile(filePath
=self
.fullPath(filePath
), type=fileType
, name
=name
, getDocCallback
=self
._getDocCallback
)
248 def findAllRefs(self
):
252 def GetXFormsDirectory(self
):
253 forms
= self
.findRefsByFileType(basedocmgr
.FILE_TYPE_XFORM
)
254 filePaths
= map(lambda form
: form
.filePath
, forms
)
255 xformdir
= os
.path
.commonprefix(filePaths
)
257 xformdir
= self
.homeDir
261 def setRefs(self
, files
):
265 def findRefsByFileType(self
, fileType
):
267 for file in self
._files
:
268 if fileType
== file.type:
269 fileList
.append(file)
273 def GenerateServiceRefPath(self
, wsdlFilePath
):
274 # HACK: temporary solution to getting wsdlag path from wsdl path.
276 from WsdlAgEditor
import WsdlAgDocument
277 ext
= WsdlAgDocument
.WSDL_AG_EXT
278 for template
in wx
.GetApp().GetDocumentManager().GetTemplates():
279 if template
.GetDocumentType() == WsdlAgDocument
:
280 ext
= template
.GetDefaultExtension()
282 wsdlAgFilePath
= os
.path
.splitext(wsdlFilePath
)[0] + ext
283 return wsdlAgFilePath
286 def SetDocCallback(self
, getDocCallback
):
287 self
._getDocCallback
= getDocCallback
288 for file in self
._files
:
289 file._getDocCallback
= getDocCallback
292 if ACTIVEGRID_BASE_IDE
:
293 class Project(BaseProject
):
296 class Project(BaseProject
, basedocmgr
.BaseDocumentMgr
):
300 class ProjectFile(object):
302 __xmlexclude__
= ('_getDocCallback', '_docCallbackCacheReturnValue', '_docModelCallbackCacheReturnValue', '_doc',)
303 __xmlattributes__
= ["filePath", "logicalFolder", "type", "name"]
304 __xmldefaultnamespace__
= xmlutils
.AG_NS_URL
307 def __init__(self
, filePath
=None, logicalFolder
=None, type=None, name
=None, getDocCallback
=None):
308 self
.filePath
= filePath
309 self
.logicalFolder
= logicalFolder
312 self
._getDocCallback
= getDocCallback
313 self
._docCallbackCacheReturnValue
= None
314 self
._docModelCallbackCacheReturnValue
= None
318 def _GetDocumentModel(self
):
319 # possible bug is if document gets replaced outside of IDE, where we'll return previous doc.
320 # originally added a timestamp check but that increased the time again to 4x
321 if self
._docModelCallbackCacheReturnValue
: # accelerator for caching document, got 4x speed up.
322 return self
._docModelCallbackCacheReturnValue
324 if self
._getDocCallback
:
325 self
._docCallbackCacheReturnValue
, self
._docModelCallbackCacheReturnValue
= self
._getDocCallback
(self
.filePath
)
326 return self
._docModelCallbackCacheReturnValue
331 document
= property(_GetDocumentModel
)
334 def _GetDocument(self
):
335 # Hack, just return the IDE document wrapper that corresponds to the runtime document model
336 # callers should have called ".document" before calling ".ideDocument"
337 if self
._docCallbackCacheReturnValue
: # accelerator for caching document, got 4x speed up.
338 return self
._docCallbackCacheReturnValue
342 ideDocument
= property(_GetDocument
)
345 def _typeEnumeration(self
):
346 return basedocmgr
.FILE_TYPE_LIST
349 def _GetPhysicalFolder(self
):
352 dir = os
.path
.dirname(self
.filePath
)
354 dir = dir.replace(os
.sep
, '/') # require '/' as delimiter
358 physicalFolder
= property(_GetPhysicalFolder
)
361 def GetRelativeFolder(self
, parentPath
):
362 parentPathLen
= len(parentPath
)
366 dir = os
.path
.dirname(self
.filePath
)
367 if dir.startswith(parentPath
):
368 dir = "." + dir[parentPathLen
:] # convert to relative path
370 dir = dir.replace(os
.sep
, '/') # always save out with '/' as path separator for cross-platform compatibility.
374 def AbsToRelativePath(self
, parentPath
):
375 """ Used to convert path to relative path for saving (disk format) """
376 parentPathLen
= len(parentPath
)
378 if self
.filePath
.startswith(parentPath
):
379 self
.filePath
= "." + self
.filePath
[parentPathLen
:] # convert to relative path
381 self
.filePath
= self
.filePath
.replace(os
.sep
, '/') # always save out with '/' as path separator for cross-platform compatibility.
383 pass # not a decendant of project, use absolute path
386 def RelativeToAbsPath(self
, parentPath
):
387 """ Used to convert path to absolute path (for any necessary disk access) """
388 if self
.filePath
.startswith("."): # relative to project file
389 self
.filePath
= os
.path
.normpath(os
.path
.join(parentPath
, self
.filePath
))
392 #----------------------------------------------------------------------------
393 # BaseDocumentMgr methods
394 #----------------------------------------------------------------------------
397 # HACK: temporary solution.
399 import wx
.lib
.docview
401 docMgr
= wx
.GetApp().GetDocumentManager()
403 doc
= docMgr
.CreateDocument(self
.filePath
, docMgr
.GetFlags()|wx
.lib
.docview
.DOC_SILENT|wx
.lib
.docview
.DOC_OPEN_ONCE|wx
.lib
.docview
.DOC_NO_VIEW
)
404 if (doc
== None): # already open
405 docs
= docMgr
.GetDocuments()
407 if d
.GetFilename() == self
.filePath
:
414 def _GetLocalServiceProcessName(self
):
415 # HACK: temporary solution to getting process name from wsdlag file.
416 return self
._GetDoc
().GetModel().processName
419 processName
= property(_GetLocalServiceProcessName
)
422 def _GetStateful(self
):
423 # HACK: temporary solution to getting stateful from wsdlag file.
424 return self
._GetDoc
().GetModel().stateful
427 def _SetStateful(self
, stateful
):
428 # HACK: temporary solution to setting stateful from wsdlag file.
429 self
._GetDoc
().GetModel().stateful
= stateful
432 stateful
= property(_GetStateful
, _SetStateful
)
435 def _GetLocalServiceCodeFile(self
):
436 # HACK: temporary solution to getting class name from wsdlag file.
437 return self
._GetDoc
().GetModel().localServiceCodeFile
440 def _SetLocalServiceCodeFile(self
, codefile
):
441 # HACK: temporary solution to setting class name from wsdlag file.
442 self
._GetDoc
().GetModel().localServiceCodeFile
= codefile
445 localServiceCodeFile
= property(_GetLocalServiceCodeFile
, _SetLocalServiceCodeFile
)
448 def _GetLocalServiceClassName(self
):
449 # HACK: temporary solution to getting class name from wsdlag file.
450 return self
._GetDoc
().GetModel().localServiceClassName
453 def _SetLocalServiceClassName(self
, className
):
454 # HACK: temporary solution to setting class name from wsdlag file.
455 self
._GetDoc
().GetModel().localServiceClassName
= className
458 localServiceClassName
= property(_GetLocalServiceClassName
, _SetLocalServiceClassName
)
462 # only activate this code if we programatically need to access these values
463 ## def _GetRssServiceBaseURL(self):
464 ## return self._GetDoc().GetModel().rssServiceBaseURL
467 ## def _SetRssServiceBaseURL(self, baseURL):
468 ## self._GetDoc().GetModel().rssServiceBaseURL = baseURL
471 ## rssServiceBaseURL = property(_GetRssServiceBaseURL, _SetRssServiceBaseURL)
474 ## def _GetRssServiceRssVersion(self):
475 ## return self._GetDoc().GetModel().rssServiceRssVersion
478 ## def _SetRssServiceRssVersion(self, rssVersion):
479 ## self._GetDoc().GetModel().rssServiceRssVersion = rssVersion
482 ## rssServiceRssVersion = property(_GetRssServiceRssVersion, _SetRssServiceRssVersion)
485 def _GetServiceRefServiceType(self
):
486 # HACK: temporary solution to getting service type from wsdlag file.
487 model
= self
._GetDoc
().GetModel()
488 if hasattr(model
, 'serviceType'):
489 return model
.serviceType
494 def _SetServiceRefServiceType(self
, serviceType
):
495 # HACK: temporary solution to getting service type from wsdlag file.
496 self
._GetDoc
().GetModel().serviceType
= serviceType
499 serviceType
= property(_GetServiceRefServiceType
, _SetServiceRefServiceType
)
502 def getExternalPackage(self
):
503 # HACK: temporary solution to getting custom code filename from wsdlag file.
504 import activegrid
.server
.deployment
as deploymentlib
506 appInfo
= self
._GetDoc
().GetAppInfo()
508 if appInfo
.language
== None:
509 language
= deploymentlib
.LANGUAGE_DEFAULT
511 language
= appInfo
.language
513 if language
== deploymentlib
.LANGUAGE_PYTHON
:
515 elif language
== deploymentlib
.LANGUAGE_PHP
:
517 pyFilename
= self
.name
+ suffix
518 return self
._GetDoc
().GetAppDocMgr().fullPath(pyFilename
)
521 #----------------------------------------------------------------------------
523 #----------------------------------------------------------------------------
526 """ Version 1.0, kept for upgrading to latest version. Over time, this should be deprecated. """
527 __xmlname__
= "project"
528 __xmlrename__
= { "_files":"files"}
529 __xmlexclude__
= ('fileName',)
530 __xmlattributes__
= ["version"]
534 self
.version
= PROJECT_VERSION_050730
538 def initialize(self
):
539 """ Required method for xmlmarshaller """
543 def upgradeVersion(self
):
544 currModel
= Project()
545 for file in self
._files
:
546 currModel
._files
.append(ProjectFile(file))