Home > Class Reference > ENSLIB namespace > %CSP.Portal.SourceControl.Base
Private  Storage   


abstract class %CSP.Portal.SourceControl.Base extends %CSP.Portal.SourceControl.Util

This class is for internal InterSystems use only. The class is subject to change and should not be used by user applications.

Template for portal pages which need to be able to interact with Source Control hooks. This class implements various interfaces and behaviours into the standard Studio patterns used for %Studio.SourceControl.Base. Note that the browser environment is inherently stateless, so the object implementing the source control hooks needs to be created from scratch every time the browser makes a request back to the server. Source control hooks written for the Studio environment will need to adjust for this situation. To assist in this migration, the hooks can should override the OnPortalCreate() callback that is inherited from %Studio.SourceControl.Base to ensure that the Source Control object is correctly initialised whenever it is created.

Users should also modify the behaviour of any Studio templates invoked from their source control hooks.

It is critical that pages which extend this class implement a number of callbacks. The following methods MUST be overridden:

The following methods may also need to be overridden depending on the page: Furthermore, the user MUST ensure that the following methods are called from the subclass: It is also assumed that a Zen jsonProvider instance is used to represent the data model in the page. The object used for the model MUST extend %CSP.Portal.AbstractPortalModel OR include a Timestamp property and a ReadOnly property as per the interface defined in %CSP.Portal.AbstractPortalModel if custom JSON is sent from the server to the client. These two properties are used to ensure that the client and server versions of the document model are synchronised. Furthermore, the OnSubmitContent callback implemented in the page MUST perform a number of actions.

First, it must support two save modes. The first such mode is a standard save mode. The value of the command string for this mode should be specified in the getSaveAction() callback. When this standard save mode is specified, the server method must check whether the timestamp of the model on disk matches the Timestamp property of the submitted model. If they don't match, the error property of the supplied jsonProvider instance should be set to the string "timestamp". When the page sees this error, the user will be prompted to decide if they want to overwrite the data on the server. If the user does choose to overwrite the data, then getSaveAction() will be invoked to get the force save action. In this case, the OnSubmitContent callback should NOT perform any timestamp checks -- the model should be saved to disk.

If the timestamps match, or the force command is supplied, and the model is saved to disk, the method should then ensure that an updated model is sent back to the client in the output object argument of the callback. The updated model should include both the new Timestamp for the document as well as a valid ReadOnly value. In this case, a valid ReadOnly value should be determined as follows:

A sample OnSubmitContent callback method could look like the following:
Method SubmitModel(
	pCommand As %String,
	pProvider As %ZEN.Auxiliary.jsonProvider,
	pSubmitObject As %RegisteredObject,
	ByRef pResponseObject As %RegisteredObject) As %Status
	Set tSC = $$$OK
	Try {
			Set tReadOnly = 0
		If (pCommand '= "forcesave") && ##class(%Dictionary.ClassDefinition).%ExistsId(..modelClassName) {
			// Note that 1 is passed in for the pExclusiveOnly argument as we need an exclusive lock
			Set tSC = ..LoadClassDefinition(..modelClassName,.tModelDef,.tReadOnly,1)
			If $$$ISERR(tSC) Quit
			If $zdatetime(tModelDef.TimeChanged,3,,6) '= pSubmitObject.Timestamp {
				Set pProvider.error = "timestamp"
		Set tSC = pSubmitObject.SaveToClass()
		If $$$ISERR(tSC) Quit
		// send up-to-date model back to client, this should include updated timestamp
		Set pResponseObject = pSubmitObject
		// correct the ReadOnly flag on the response object
		If ..IsSourceControlReadOnly(..GetInternalName()) {
			Set pResponseObject.ReadOnly = 2
		Else {
			Set pResponseObject.ReadOnly = tReadOnly
	Catch(ex) {
		Set tSC = ex.AsStatus()
	Quit tSC


Parameters Properties Methods Queries Indices ForeignKeys Triggers
4 16 54


canEdit currentNamespace currentProject currentUser
hasSCOutput msgNotPermitted needProject readOnly
readOnlyReason renamed sourceControlEnabled sourceControlManagerDialog
sourceControlNewlineFormat sourceControlOutputDialog sourceControlVisible

%DrawSourceControlCommands %DrawSourceControlHead %DrawSourceControlJS %DrawSourceControlStyle
AfterUserAction AppendSourceControlOutput ClearSourceControlOutput CreateProject
CreateSourceControl DocumentLoad DocumentSave GetCurrentProject
GetFullProjectName GetInternalName GetSourceControlClass GetSourceControlCommands
GetTimestamp HaveSourceControlOutput IsEnabled IsProjectRequired
IsSourceControlReadOnly LoadProject SetCurrentProject SetProjectRequired
UpdateSCMenus UserAction appendServerOutput canUserModify
checkTextControls chooseSCMenu chooseSCProject clearSCOutput
createSCMenuItem createSCProject createSCSubMenu getClientModel
getCurrentExtension getCurrentName getReadOnlyReason getSaveAction
initializeSourceControl initializeTextMonitor invokeAfterUserAction invokeSourceControl
loadDocument onDocumentLoad onDocumentLoadComplete onDocumentSave
onDocumentSaveComplete onloadHandler reloadDocument saveDocument
setPageTitle setReadOnly setSCProject showSCMenu
showSCOutput textControlKeyDown textControlKeyUp updateDocumentState

%DeepSee.UI.Architect %DeepSee.UI.ArchitectSA %DeepSee.UI.QualityMeasures
%DeepSee.UserPortal.Application %DeepSee.UserPortal.DashboardViewer EnsPortal.Template.devPage


• parameter DOMAIN = "%Utility";
• parameter EDITRESOURCE;
Resource for subclasses to indicate whether further resources are needed to perform actions on pages.
• parameter MANAGERDIALOG = "_CSP.Portal.SourceControl.Dialog.Manager.zen";
Page to use for managing popups requested by the source control framework.
• parameter OUTPUTDIALOG = "_CSP.Portal.SourceControl.Dialog.ServerOutput.zen";
Page to use for displaying output from the server.


• property canEdit as %ZEN.Datatype.boolean [ InitialExpression = 1 ];
Flag to indicate whether the user is permitted to make any changes on a given page.
• property currentNamespace as %ZEN.Datatype.string [ InitialExpression = $namespace ];
The current namespace.
• property currentProject as %ZEN.Datatype.string(MAXLEN=68) [ InitialExpression = ..GetCurrentProject() ];
The name of the currently active/selected project.
• property currentUser as %ZEN.Datatype.string [ InitialExpression = $username ];
The current user's username
• property hasSCOutput as %ZEN.Datatype.boolean [ InitialExpression = ..HaveSourceControlOutput() ];
Flag to indicate whether source control output is present in the current session.
• property msgNotPermitted as %ZEN.Datatype.caption [ InitialExpression = $$$TextJS("You are not permitted to perform this action","%Utility") ];
Message to inform the user they may not perform a given action.
• property needProject as %ZEN.Datatype.boolean [ InitialExpression = ..IsProjectRequired() ];
Flag to indicate whether a project is needed for the current source control hooks.
• property readOnly as %ZEN.Datatype.boolean [ InitialExpression = 0 ];
If true, user cannot modify the current document.
• property readOnlyReason as %ZEN.Datatype.string;
Indicator for why a document was marked as readOnly. When readOnly is true, the updateDocumentState() is responsible for ensuring that the property should either have a value of "sourcecontrol" or "lock".
• property renamed as %ZEN.Datatype.boolean [ InitialExpression = 0 ];
Flag to indicate whether the document has been renamed via "Save As".
• property sourceControlEnabled as %ZEN.Datatype.boolean [ InitialExpression = ..IsEnabled($namespace) ];
Flag to indicate whether source control hooks are enabled for the current namespace.
• property sourceControlManagerDialog as %ZEN.Datatype.string [ InitialExpression = ..#MANAGERDIALOG ];
Name of the manager page to use for managing popups requested by the source control class.
• property sourceControlNewlineFormat as %ZEN.Datatype.string [ InitialExpression = "HTML" ];
Flag to control what newline format should be used for reporting data from the server. The default output is HTML.
• property sourceControlOutputDialog as %ZEN.Datatype.string [ InitialExpression = ..#OUTPUTDIALOG ];
Name of the output dialog to use.
• property sourceControlVisible as %ZEN.Datatype.boolean [ InitialExpression = 0 ];
Flag to indicate whether the source control output is currently visible.


• method %DrawSourceControlCommands() as %Status
This is a helper method to render the default HTML for the source control options in the ribbon, and should be called from the OnDrawRibbon() callback. This content should be wrapped within a td element.
• method %DrawSourceControlHead() as %Status
The subclass should invoke this method from its own %OnDrawHTMLHead() method.
• method %DrawSourceControlJS() as %Status
Ensure that zenMenus.js and zenCSLM.js are included in the page.
• method %DrawSourceControlStyle() as %Status
Render the CSS needed for the source control icons.
• classmethod AfterUserAction(pInputProxy As %ZEN.proxyObject, pOutputProxy As %ZEN.proxyObject, pUserData As %ZEN.proxyObject) as %String [ ZenMethod ]
Server-side wrapper around the AfterUserAction callback.
• classmethod AppendSourceControlOutput(pOutput As %String = "") [ ZenMethod ]
Add output to the session data on the server.
• classmethod ClearSourceControlOutput() as %Integer [ ZenMethod ]
Clear the output for the session.
• classmethod CreateProject(pInputProxy As %ZEN.proxyObject, pOutputProxy As %ZEN.proxyObject) [ ZenMethod ]
Create a new Studio project on the server.
• classmethod DocumentLoad(pInputProxy As %ZEN.proxyObject, pOutputProxy As %ZEN.proxyObject) as %String [ ZenMethod ]
Implement the correct callbacks around loading a document.
• classmethod DocumentSave(pInputProxy As %ZEN.proxyObject, pOutputProxy As %ZEN.proxyObject) as %String [ ZenMethod ]
Implement the correct callbacks around saving a document.
• method GetInternalName() as %String
Return the internal name of the current document, including the three letter extension in upper-case. For example, MyPackage.MyClass.CLS would be the internal name for the class MyPackage.MyClass. Subclasses MUST override this method.
• classmethod GetSourceControlCommands(Output pDisplay As %Boolean, Output pCommands, Output pNeedProject As %Boolean, Output pServerOutput As %String) as %Status
Determine which source control commands should be drawn for the current context.
• classmethod GetTimestamp(classname As %String = "") as %String [ ZenMethod ]
Get the timestamp for the current document.
• classmethod HaveSourceControlOutput() as %Boolean
Indicate whether there is Source Control output for the session.
• classmethod IsSourceControlReadOnly(pInternalName As %String = "") as %Boolean
• classmethod LoadProject(pSourceControl As %Studio.SourceControl.Base, pProject As %String, pRedirect As %Boolean = 1) as %Status
Load the named project in pProject using the source control object supplied in pSourceControl. The pRedirect flag controls whether a local redirect should be created.
• method UpdateSCMenus(showMenu As %Boolean = 0) as %String [ ZenMethod ]
Update the _sourceControlMenu Javascript object representing the contents of the source control menus.
• classmethod UserAction(pInputProxy As %ZEN.proxyObject, pOutputProxy As %ZEN.proxyObject) as %String [ ZenMethod ]
Server-side wrapper around the UserAction callback.
• method appendServerOutput(data, first) [ Language = javascript ]
Render the server output from source control commands on the client.
• method canUserModify(noAlert) [ Language = javascript ]
Helper method to indicate whether the user is allowed to make changes to the current document. It should check whether the user is allowed to make changes in general (which should be indicated by canEdit), as well as whether the current document has been opened in read only mode (which should be indicated by canEdit). noAlert is a flag to indicate that the check should not raise an alert.
• method checkTextControls() [ Language = javascript ]
Helper method for event sequencing: the onmousedown event for the menu buttons and shapes in the SVG diagram may be executed before the onchange event for controls in the editor pane. This helper function will call the onchange event for any controls which have had their value changed. (There should only be one such control in most cases as the onchange event would be triggered when shifting focus to a second control.)
• method chooseSCMenu(menuName, commandName, saveFlags) [ Language = javascript ]
Handle a source control menu selection.
• method chooseSCProject(projectName, isNew) [ Language = javascript ]
The user has selected on of the projects listed in the dropdown.
• method clearSCOutput() [ Language = javascript ]
Clear the source control output on the server and update the content star.
• method createSCMenuItem(parentItem, caption, onselect) [ Language = javascript ]
Helper method to create an item in the source control menu.
• method createSCProject(projectName) [ Language = javascript ]
Create a new project on the server.
• method createSCSubMenu(parentItem, caption) [ Language = javascript ]
Helper method to create a submenu in the source control menu.
• method getClientModel() [ Language = javascript ]
Get the jsonProvider object on the client. Subclasses MUST override this method to return the jsonProvider.
• method getCurrentExtension() [ Language = javascript ]
Return the extension used by Studio for the class/object. This is ".CLS" by default, but subclasses should override this method if a different extension is in use.
• method getCurrentName() [ Language = javascript ]
Return the current name of the class/object being modified. Subclasses MUST override this method to return the correct name.
• method getReadOnlyReason() [ Language = javascript ]
Callback to get the text of the reason for the current document being loaded as readonly.
• method getSaveAction(force) [ Language = javascript ]
Return the string used as the command when sending JSON content to the server. The OnSubmitContent handler for the jsonProvider MUST support two action types.
• method initializeSourceControl() [ Language = javascript ]
Function to initialize the source control hooks for a page. The function should be called from the subclass's onloadHandler() method.
• method initializeTextMonitor() [ Language = javascript ]
Initialize the text monitor for the page.
• method invokeAfterUserAction(input, userContext) [ Language = javascript ]
Client-side coordinator of calls to the AfterUserAction callback in the core source control class.
• method invokeSourceControl(action, isFramework) [ Language = javascript ]
Client-side coordinator of calls to the UserAction callback in the core source control class.
• method loadDocument() [ Language = javascript ]
Method to load document from the client and invoke the correct source control hooks.
• method onDocumentLoad(when, documentName) [ Language = javascript ]
Callback invoked when a document is being loaded.
• method onDocumentLoadComplete() [ Language = javascript ]
Callback method invoked after we have successfully loaded the current document.
• method onDocumentSave(when, documentName) [ Language = javascript ]
Callback invoked when a document is being saved.
• method onDocumentSaveComplete(contentModified) [ Language = javascript ]
Callback method invoked after we successfully save the current document.
• method onloadHandler() [ Language = javascript ]
Add check to ensure that we correctly load documents on the client when source control hooks are in use.
• method reloadDocument() [ Language = javascript ]
Reload the current document. Returns a boolean to indicate whether a full page reload has been triggered.
• method saveDocument(force) [ Language = javascript ]
Save the current document using the correct source control hooks.
• method setPageTitle(newTitle) [ Language = javascript ]
Set the title of the page
• method setReadOnly(readOnly) [ Language = javascript ]
Set readOnly to the value of readOnly. Subclasses MUST implement this method to update the controls on the page so that the page's behaviour actually matches the value of the readOnly flag.
• method setSCProject(newProject) [ Language = javascript ]
Notify the server that a specific project has been chosen.
• method showSCMenu() [ Language = javascript ]
Display the source control menu based on the contents of the _sourceControlMenu data created by UpdateSCMenu().
• method showSCOutput() [ Language = javascript ]
Open a popup to display the current source control output.
• method textControlKeyDown(zenControl) [ Language = javascript ]
Key handler to record the value of text fields before the keyboard event is processed. Works in conjunction with textControlKeyUp() to determine whether any text fields are modified.
• method textControlKeyUp(event, zenControl) [ Language = javascript ]
Key handler to work out whether user keys entered in controls have changed the content of the text field. This is to deal with situations where the onchange event for a text control is only triggered after the onmousedown event for another shape has already occurred.
• method updateDocumentState(alertOnReadOnly) [ Language = javascript ]
Helper method to ensure that the readOnly and readOnlyReason properties are up to date on the client, and that the user knows about any change that has rendered the document read only.
• method updateSCIndicator(haveOutput) [ Language = javascript ]
Toggle the display of the star which indicates whether new source control output is available.