Extract key/value pairs js file - msbuild

Trough msbuild target tag i am copy a file (if exist) to a new target and changing his name (it is working properly):
<!--///////////////////////////Target CopyOldWebConfigJs//////////////////////////////////////////////-->
<Target Name="CopyOldWebConfigJs" Inputs="#(ContentFiltered)" Outputs="%(Identity).Dummy" DependsOnTargets="webConfigJsCase">
<Exec
Command= "copy "D:\p\Deployments\p\\WebPages\web.config.js" "$(AssemblyRoot)\WebPages\web.config.serverCopy.js""
/>
</Target>
<!-- New target to pre-filter list -->
<Target Name="webConfigJsCase"
Inputs="#(FileToPublish)"
Outputs="%(Identity).Dummy">
<ItemGroup>
<ContentFiltered Include="#(FileToPublish)" Condition="$([System.Text.RegularExpressions.Regex]::IsMatch('%(FileToPublish.Filename)%(FileToPublish.Extension)', 'web.config.js')) AND Exists('D:\\p\\Deployments\\p\\WebPages\\web.config.js')" />
</ItemGroup>
</Target>
<!--///////////////////////////End Target CopyOldWebConfigJs//////////////////////////////////////////////-->
The target file web.config.serverCopy.js is a file that have key/value pair content:
///////////////////////////////// TEST VERSION //////////////////////////////////////////////
//This is used for general web config settings for .js scripts that _webconfig. from staging to production
//It should not be edited or copied
_webconfig = new Object();
_webconfig.env = "pageq03"; // Needs Replacing
_webconfig.deployment = "p"; // Needs Replacing
_webconfig.relativeWebServicePath = "../WS/"; // Needs Replacing
_webconfig.webServiceFileName = "API.asmx"; // Needs Replacing
_webconfig.errorReportingThreshhold = "High"; // Setting for reporting bugs via email. Set to "Low" to report everything. ["Low", "Normal", "High" or "None"]
_webconfig.customPreviewPhaseDuration = 1000; //Setting that controls how long the automatic preview sits and resolves conflicts prior to showing the preview. Higher numbers increase performance while lower numbers enchance user experience.
//_webconfig.NewRelicAppID = {4}; //2805166
//J.A.C.K.A.L. settings (all false by default)
_webconfig.skipBootstrap = false;
_webconfig.skipJqueryUI = false;
_webconfig.skipPOCommon = false;
_webconfig.skipPOCampaignPreviews = false;
_webconfig.skipPOAjaxMonitor = false;
_webconfig.skipIconFonts = false;
_webconfig.skipCookie = false;
_webconfig.skipTouchPunch = false;
_webconfig.skipWebFont = false;
_webconfig.skipJSON = false;
_webconfig.skipKnob = false;
_webconfig.skipGoogleCharts = false;
_webconfig.jqueryuiTheme = "redmond";
//preview scrolling
_webconfig.previewScrollType = "always"; //none | onRender | onChange | Always
_webconfig.previewScrollSpeed = 500; //in milliseconds
//Dyanamic Menu
_webconfig.openMenuLinksInSearch = true;
//WIDGET SETTINGS
_webconfig.masterWidgetPath = "widgets/"; //end '/' required
_webconfig.widgetAnimateResize = false;
_webconfig.widgetAnimateSpeed = 100; //ms
_webconfig.widgetDestroyAnimationSpeed = 900;
_webconfig.widgetDebugModeOn = false;
_webconfig.widgetULIdToUse = "widgetSortable";
_webconfig.widgetToolbarAnchor = "#tblNavigationBar";
_webconfig.widgetFavoritesMiniMenuAnchor = ".navBarRight";
_webconfig.widgetScrollToDuration = 700; //in milliseconds
_webconfig.widgetSelectionIndicatorPhaseDuration = .5; //in seconds
_webconfig.widgetSelectionIndicatorNumOfPhases = 4;
_webconfig.allowUseOfWidgetFavorites = true;
_webconfig.POServicesAppName = "p.PO.Services"; // Needs Replacing
Now after copying it (backup it), I have 2 missions, i need to read his content and
Save the value that _webconfig.deployment holds - that value need to replace the path of the source path CopyOldWebConfigJs target tag Exec commands holds(now it hard-coded) - i don't see how it can be done.
Every key/value that have the phrase // Needs Replacing at the end of it's line, i need to save it's value and insert it's content to other web.config.js on the same directory, with the same structure (same key names).
I am kinda new to MSBUILD and any help with it will be much appreciated..

Related

How to exclude certain images from autosave in Gatan Digital Micrograph (GMS) in DM-script

I am trying to mimic the autosave function in GMS v3 so that I can use in version 1 and 2. I would like to first acknowledge that the main bulk of the script originates from Dr Bernhard Schaffer's "How to script... Digital Micrograph Scripting Handbook". I have modified it a bit, so that any new image recorded by the camera can be autosave into the file. However, I met some problems because if I decide to click on live-view image and move the image around, or using live-fft, the live view image or the FFT image will be saved as well. One of the ideas I have is to use the taggroup information such as the "Acquisition:Parameters:Parameter Set Name" because for live view or live-FFT, this would be either in search or focus mode. Another idea is to use the document ID e.g iDocID = idoc.ImageDocumentGETID() to locate the ID of the live image. However, i am clueless then how to use this information to exclude them from autosaving. Can anyone point to me how i can proceed with this script?
Below is the script
Class PeriodicAutoSave : Object
{
Number output
PeriodicAutoSave(Object self) Result("\n Object ID"+self.ScriptObjectGetID()+" created.")
~PeriodicAutoSave(Object self) Result("\n Object ID"+self.ScriptObjectGetID()+" destroyed")
Void Init2(Object self, Number op)
output=op
Void AutoSave_SaveAll(Object self)
{
String path, name, targettype, targettype1, area, mag, mode, search, result1
ImageDocument idoc
Number nr_idoc, count, index_i, index, iDocID, iDocID_search
path = "c:\\path\\"
name = "test"
targettype=="Gatan Format (*.dm4)"
targettype1 = "dm4"
If (output) Result("\n AutoSave...")
nr_idoc = CountImageDocuments()
For (count = 1; count<nr_idoc; count++)
{
idoc = GetImageDocument(count) //imagedocument
index = 1 // user decide the index to start with
index_i= nr_idoc - index
If (idoc.ImageDocumentIsDirty())
{
idoc = getfrontimagedocument()
iDocID = idoc.ImageDocumentGetID()
TagGroup tg = ImageGetTagGroup(idoc.ImageDocumentGetImage(0)) // cannot declare an 'img' for this line as it will prompt an error?
tg.TagGroupGetTagAsString("Microscope Info:Formatted Indicated Mag", mag)
Try{
{
idoc.ImageDocumentSavetoFile( "Gatan Format", path+index_i+"-"+name+"-"+mag+".dm4")
idoc.ImageDocumentSetName(index_i + "-"+name+"-"+mag+".dm4")
idoc.ImageDocumentClean()
}
If (Output) Result("\n\t saving: "+idoc.ImageDocumentGetCurrentFile())
}
Catch{
Result("\n image cannot be saved at the moment:" + GetExceptionString())
Break
}
Result("\ Continue autosave...")
}
}
}
}
Void LaunchAutoSave()
{
Object obj = Alloc(PeriodicAutoSave)
obj.Init2(2)
Number task_id = obj.AddMainThreadPeriodicTask("AutoSave_SaveALL",6)
//Sleep(10)
while(!shiftdown()) 1==2
RemoveMainThreadTask(task_id)
}
LaunchAutoSave()
thank you very much for your pointers! I have tried and it works very well with my script. as the 'TagGroupDoesTagExist' only refers to the taggroup, I modified further to include the tags I want to filter e.g "Search" or "Focus" and it seems to work well. The script that I modified to your existing ones is as below :
If (idoc.ImageDocumentIsDirty())
{
//now find out what is a filter condition and skip if it is true
skip = 0
TagGroup tg = idoc.ImageDocumentGetImage(0).ImageGetTagGroup()
tg.TagGroupGetTagAsString("Microscope Info:Formatted Indicated Mag", mag)
tg.TagGroupGetTagAsString("Acquisition:Parameters:Parameter Set Name", mode)
skip = tg.TagGroupDoesTagExist("Acquisition:Parameters:Parameter Set Name")
if(skip && (mode == "Search" || mode== "Focus")) continue
Your idea of filtering is a good one, but there is something strange with your for loop.
in
nr_idoc = CountImageDocuments()
For (count = 1; count<nr_idoc; count++)
{
idoc = GetImageDocument(count) //imagedocument
you iterate over all currently open imageDocuments (except the first one!?) and get them one by one, but then in
If (idoc.ImageDocumentIsDirty())
{
idoc = getfrontimagedocument()
you actually get the front-most (selected) document instead each time. Why are you doing this?
Why not go with:
number nr_idoc = CountImageDocuments()
for (number count = 0; count<nr_idoc; count++)
{
imagedocument idoc = GetImageDocument(count)
If (idoc.ImageDocumentIsDirty())
{
// now find out what is a filter condition and skip if it is true
number skip = 0
TagGroup tg = idoc.ImageDocumentGetImage(0).ImageGetTagGroup()
skip = tg.TagGroupDoesTagExist("Microscope Info:Formatted Indicated Mag")
if (skip) continue
// do saving
}
}

EPiServer 9 - Add block to new page programmatically

I have found some suggestions on how to add a block to a page, but can't get it to work the way I want, so perhaps someone can help out.
What I want to do is to have a scheduled job that reads through a file, creating new pages with a certain pagetype and in the new page adding some blocks to a content property. The blocks fields will be updated with data from the file that is read.
I have the following code in the scheduled job, but it fails at
repo.Save((IContent) newBlock, SaveAction.Publish);
giving the error
The page name must contain at least one visible character.
This is my code:
public override string Execute()
{
//Call OnStatusChanged to periodically notify progress of job for manually started jobs
OnStatusChanged(String.Format("Starting execution of {0}", this.GetType()));
//Create Person page
PageReference parent = PageReference.StartPage;
//IContentRepository contentRepository = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<IContentRepository>();
//IContentTypeRepository contentTypeRepository = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<IContentTypeRepository>();
//var repository = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<IContentRepository>();
//var slaegtPage = repository.GetDefault<SlaegtPage>(ContentReference.StartPage);
IContentRepository contentRepository = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<IContentRepository>();
IContentTypeRepository contentTypeRepository = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<IContentTypeRepository>();
SlaegtPage slaegtPage = contentRepository.GetDefault<SlaegtPage>(parent, contentTypeRepository.Load("SlaegtPage").ID);
if (slaegtPage.MainContentArea == null) {
slaegtPage.MainContentArea = new ContentArea();
}
slaegtPage.PageName = "001 Kim";
//Create block
var repo = ServiceLocator.Current.GetInstance<IContentRepository>();
var newBlock = repo.GetDefault<SlaegtPersonBlock1>(ContentReference.GlobalBlockFolder);
newBlock.PersonId = "001";
newBlock.PersonName = "Kim";
newBlock.PersonBirthdate = "01 jan 1901";
repo.Save((IContent) newBlock, SaveAction.Publish);
//Add block
slaegtPage.MainContentArea.Items.Add(new ContentAreaItem
{
ContentLink = ((IContent) newBlock).ContentLink
});
slaegtPage.URLSegment = UrlSegment.CreateUrlSegment(slaegtPage);
contentRepository.Save(slaegtPage, EPiServer.DataAccess.SaveAction.Publish);
_stopSignaled = true;
//For long running jobs periodically check if stop is signaled and if so stop execution
if (_stopSignaled) {
return "Stop of job was called";
}
return "Change to message that describes outcome of execution";
}
You can set the Name by
((IContent) newBlock).Name = "MyName";

ColdFusion CFDOCUMENT with links to other PDFs

I am creating a PDF using the cfdocument tag at the moment. The PDF is not much more than a bunch of links to other PDFs.
So I create this PDF index and the links are all HREFs
Another PDF
if I set the localURL attribute to "no" my URLs have the whole web path in them:
Another PDF
if I set the localURL attribute to "yes" then I get:
Another PDF
So this index PDF is going to go onto a CD and all of the linked PDFs are going to sit right next to it so I need a relative link ... more like:
Another PDF
cfdocument does not seem to do this. I can modify the file name of the document and make it "File:///Another_PDF.pdf" but this does not work either because I don't know the driveletter of the CD drive ... or if the files are going to end up inside a directory on the CD.
Is there a way (possibly using iText or something) of opening up the PDF once it is created and converting the URL links to actual PDF GoTo tags?
I know this is kind of a stretch but I am at my wits end with this.
So I've managed to get into the Objects but I'm still struggling with.
Converting from:
5 0 obj<</C[0 0 1]/Border[0 0 0]/A<</URI(File:///75110_002.PDF)/S/URI>>/Subtype/Link/Rect[145 502 184 513]>>endobj
To this:
19 0 obj<</SGoToR/D[0/XYZ null null 0]/F(75110_002.PDF)>>endobj
20 0 obj<</Subtype/Link/Rect[145 502 184 513]/Border[0 0 0]/A 19 0 R>>endobj
Wow this is really kicking my ass! :)
So I've managed to get the document open, loop through the Link Annotations, capture the Rect co-ordinates and the linked to document name (saved into an array of Structures) and then successfully deleted the Annotation which was a URI Link.
So now I thought I could now loop over that array of structures and put the Annotations back into the document using the createLink method or the setAction method. But all the examples I've seen of these methods are attached to a Chunk (of text). But my document already has the Text in place so I don't need to remake the text links I just need to put the Links back in in the same spot.
So I figured I could reopen the document and look for the actual text that was the link and then attache the setAction to th ealready existing chunk of text .... I can't find the text!!
I suck! :)
This thread has an example of updating the link actions, by modifying the pdf annotations. It is written in iTextSharp 5.x, but the java code is not much different.
The thread provides a solid explanation of how annotations work. But to summarize, you need to read in your source pdf and loop through the individual pages for annotations. Extract the links and use something like getFileFromPath() to replace them with a file name only.
I was curious, so I did a quick and ugly conversion of the iTextSharp code above. Disclaimer, it is not highly tested:
/**
Usage:
util = createObject("component", "path.to.ThisComponent");
util.fixLinks( "c:/path/to/sourceFile.pdf", "c:/path/to/newFile.pdf");
*/
component {
/**
Convert all absolute links, in the given pdf, to relative links (file name only)
#source - absolute path to the source pdf file
#destination - absolute path to save copy
*/
public function fixLinks( string source, string destination) {
// initialize objects
Local.reader = createObject("java", "com.lowagie.text.pdf.PdfReader").init( arguments.source );
Local.pdfName = createObject("java", "com.lowagie.text.pdf.PdfName");
// check each page for hyperlinks
for ( Local.i = 1; Local.i <= Local.reader.getNumberOfPages(); Local.i++) {
//Get all of the annotations for the current page
Local.page = Local.reader.getPageN( Local.i );
Local.annotations = Local.page.getAsArray( Local.PdfName.ANNOTS ).getArrayList();
// search annotations for links
for (Local.x = 1; !isNull( Local.annotations) && Local.x < arrayLen(Local.annotations); Local.x++) {
// get current properties
Local.current = Local.annotations[ Local.x ];
Local.dictionary = Local.reader.getPdfObject( Local.current );
Local.subType = Local.dictionary.get( Local.PdfName.SUBTYPE );
Local.action = Local.dictionary.get( Local.PdfName.A );
Local.hasLink = true;
//Skip this item if it does not have a link AND action
if (Local.subType != Local.PdfName.LINK || isNull(Local.action)) {
Local.hasLink = false;
}
//Skip this item if it does not have a URI
if ( Local.hasLink && Local.action.get( Local.PdfName.S ) != Local.PdfName.URI ) {
Local.hasLink = false;
}
//If it is a valid URI, update link
if (Local.hasLink) {
// extract file name from URL
Local.oldLink = Local.action.get( Local.pdfName.URI );
Local.newLink = getFileFromPath( Local.oldLink );
// replace link
// WriteDump("Changed link from ["& Local.oldLink &"] ==> ["& Local.newLink &"]");
Local.pdfString = createObject("java", "com.lowagie.text.pdf.PdfString");
Local.action.put( Local.pdfName.URI, Local.pdfString.init( Local.newLink ) );
}
}
}
// save all pages to new file
copyPDF( Local.reader , arguments.destination );
}
/**
Copy all pages in pdfReader to the given destination file
#pdfReader - pdf to copy
#destination - absolute path to save copy
*/
public function copyPDF( any pdfReader, string destination) {
try {
Local.doc = createObject("java", "com.lowagie.text.Document").init();
Local.out = createObject("java", "java.io.FileOutputStream").init( arguments.destination );
Local.writer = createObject("java", "com.lowagie.text.pdf.PdfCopy").init(Local.doc, Local.out);
// open document and save individual pages
Local.doc.open();
for (Local.i = 1; i <= arguments.pdfReader.getNumberOfPages(); Local.i++) {
Local.writer.addPage( Local.writer.getImportedPage( arguments.pdfReader, Local.i) );
}
Local.doc.close();
}
finally
{
// cleanup
if (structKeyExists(Local, "doc")) { Local.doc.close(); }
if (structKeyExists(Local, "writer")) { Local.writer.close(); }
if (structKeyExists(Local, "out")) { Local.out.close(); }
}
}
}
I finally got it:
public function resetLinks( string source, string destination) {
try {
// initialize objects
Local.reader = createObject("java", "com.lowagie.text.pdf.PdfReader").init( arguments.source );
Local.pdfName = createObject("java", "com.lowagie.text.pdf.PdfName");
Local.annot = createObject("java", "com.lowagie.text.pdf.PdfAnnotation");
Local.out = createObject("java", "java.io.FileOutputStream").init( arguments.destination );
Local.stamper = createObject("java", "com.lowagie.text.pdf.PdfStamper").init(Local.reader, Local.out);
Local.PdfAction = createObject("java", "com.lowagie.text.pdf.PdfAction");
Local.PdfRect = createObject("java", "com.lowagie.text.Rectangle");
Local.PdfBorderArray = createObject("java", "com.lowagie.text.pdf.PdfBorderArray").init(javacast("float", "0"), javacast("float", "0"), javacast("float", "0"));
Local.newAnnots = [];
// check each page for hyperlinks
// Save the data to a structure then write it to an array
// then delete the hyperlink Annotation
for ( Local.i = 1; Local.i <= Local.reader.getNumberOfPages(); Local.i = Local.i + 1) {
//Get all of the annotations for the current page
Local.page = Local.reader.getPageN( Local.i );
Local.annotations = Local.page.getAsArray( Local.PdfName.ANNOTS ).getArrayList();
// search annotations for links
for (Local.x = arrayLen(Local.annotations); !isNull( Local.annotations) && Local.x > 0; Local.x--) {
// get current properties
Local.current = Local.annotations[ Local.x ];
Local.dictionary = Local.reader.getPdfObject( Local.current );
Local.subType = Local.dictionary.get( Local.PdfName.SUBTYPE );
Local.action = Local.dictionary.get( Local.PdfName.A );
Local.hasLink = true;
//Skip this item if it does not have a link AND action
if (Local.subType != Local.PdfName.LINK || isNull(Local.action)) {
Local.hasLink = false;
}
//Skip this item if it does not have a URI
if ( Local.hasLink && Local.action.get( Local.PdfName.S ) != Local.PdfName.URI ) {
Local.hasLink = false;
}
//If it is a valid URI, update link
if (Local.hasLink) {
// extract file name from URL
Local.oldLink = Local.action.get( Local.pdfName.URI );
Local.newLink = getFileFromPath( Local.oldLink );
Local.Rect = Local.dictionary.Get(PdfName.Rect);
arrayStruct = StructNew();
arrayStruct.rectSTR = Local.Rect.toString();
arrayStruct.link = Local.newLink;
arrayStruct.page = Local.i;
ArrayAppend(Local.newAnnots, arrayStruct);
// Delete
Local.annotations.remove(Local.current);
}
}
}
// Now really remove them!
Local.reader.RemoveUnusedObjects();
// Now loop over the saved annotations and put them back!!
for ( Local.z = 1; Local.z <= ArrayLen(Local.newAnnots); Local.z++) {
// Parse the rect we got save into an Array
theRectArray = ListToArray(ReplaceNoCase(ReplaceNoCase(Local.newAnnots[z].rectSTR, "[", ""), "]", ""));
// Create the GoToR action
theAction = Local.PdfAction.gotoRemotePage(javacast("string", '#Local.newAnnots[z].link#'), javacast("string", '#Local.newAnnots[z].link#'), javacast("boolean", "false"), javacast("boolean", "false"));
// Create the Link Annotation with the above Action and the Rect
theAnnot = Local.annot.createLink(Local.stamper.getWriter(), Local.PdfRect.init(javacast("int", theRectArray[1]), javacast("int", theRectArray[2]), javacast("int", theRectArray[3]), javacast("int", theRectArray[4])), Local.annot.HIGHLIGHT_INVERT, theAction);
// Remove the border the underlying underlined text will flag item as a link
theAnnot.setBorder(Local.PdfBorderArray);
// Add the Annotation to the Page
Local.stamper.addAnnotation(theAnnot, Local.newAnnots[z].page);
}
}
finally {
// cleanup
if (structKeyExists(Local, "reader")) { Local.reader.close(); }
if (structKeyExists(Local, "stamper")) { Local.stamper.close(); }
if (structKeyExists(Local, "out")) { Local.out.close(); }
}
}
I couldn't have done this without the help of Leigh!!

How can I read Variables from data pool with Selenium IDE?

I am using Selenium IDE to test a web based HR/SW system.
There is a screen that used to enter vacation for employees.
I am having nearly 3000 employee.
I built a test case that enter vacations for one employee using variables.
How can I repeat the test case for all 3000 employees without creating the test case 3000 times. It will take an impossible effort to do that. Note: Each employee is having different vacation data (Type, start date, End date)
Is there any way that I can use a file (Excel,....) that variable can use to read its data from?
Is there any solution for my case???
I will be very very grateful I any one could help me.
Thank you.
You could use an XML file as an input.
1) At first you have to add following user extensions:
sideflow.js - (http://51elliot.blogspot.com/2008/02/selenium-ide-goto.html - additionally this article explains how to add user extension files)
datadriven.js
include.js
At the moment I can't find links where I took the last two, therefore I will give their code in the end of my post. Code is taken from my working directory. You just put the code to correspondent files, then add files to SelemiunIDE user extension and use them.
2) Create an XML file test_data.xml:
<testdata>
<test employee="1" type="1" startDate="01.01.2013" endDate="01.02.2013" />
<test employee="2" type="1" startDate="01.02.2013" endDate="01.03.2013" />
<test employee="3" type="1" startDate="01.03.2013" endDate="01.04.2013" />
...
</testdata>
3) In your test case use code like this:
${DataPath} - full path to a directory with XML-files
<!--BEGIN LOOP-->
<tr>
<td>loadTestData</td>
<td>file://${DataDir}/test_data.xml</td>
<td></td>
</tr>
<tr>
<td>while</td>
<td>!testdata.EOF()</td>
<td></td>
</tr>
<tr>
<td>nextTestData</td>
<td></td>
<td></td>
</tr>
<tr>
<td>echo</td>
<td>employee=${employee} type=${type} ...</td>
<td></td>
</tr>
...
<!--END LOOP-->
<tr>
<td>endWhile</td>
<td></td>
<td></td>
</tr>
Used user extensions:
include.js
/**
* Original Developer: Jerry Qian(qqqiansjtucs#hotmail.com)
* Modified By: John Witchel (jwitchel#colevalleygroup.com)
* include extension for Selenium-IDE edition
* refer to includeCommand_2.1.3 for Selenium-Core edition
* #version 1.3
*
*/
function IDEIncludeCommand() {}
IDEIncludeCommand.LOG_PREFIX = "IDEIncludeCommand: ";
IDEIncludeCommand.BEGIN_TEMPLATE = "begin$Template$";
IDEIncludeCommand.END_TEMPLATE = "end$Template$";
IDEIncludeCommand.VERSION = "1.1";
IDEIncludeCommand.prototype.prepareTestCaseAsText = function(responseAsText, paramsArray) {
/**
* Prepare the HTML to be included in as text into the current testcase-HTML
* Strip all but the testrows (tr)
* Stripped will be:
* - whitespace (also new lines and tabs, so be careful wirt parameters relying on this),
* - comments (xml comments)
* Replace variable according to include-parameters
* note: the include-variables are replaced literally. selenium does it at execution time
* also note: all selenium-variables are available to the included commands, so mostly no include-parameters are necessary
*
* #param responseAsText table to be included as text (string)
* #return testRows array of tr elements (as string!) containing the commands to be included
*
* TODO:
* - selenium already can handle testcase-html. use selenium methods or functions instead
* - find better name for requester
*/
// removing new lines, carret return and tabs from response in order to work with regexp
var pageText = responseAsText.replace(/\r|\n|\t/g,"");
// remove comments
// begin comment, not a dash or if it's a dash it may not be followed by -> repeated, end comment
pageText = pageText.replace(/<!--(?:[^-]|-(?!->))*-->/g,"");
// find the content of the test table = <[spaces]table[char but not >]>....< /[spaces]table[chars but not >]>
var testText = pageText.match(/<\s*table[^>]*>(.*)<\/\s*table[^>]*>/i)[1];
// Replace <td></td> with <td> </td> for iE - credits Chris Astall
// rz: somehow in my IE 7 this is not needed but is not bad as well
testText = testText.replace(/<\s*td[^>]*>\s*<\s*\/td[^>]*>/ig,"<td></td>");// jq: no space
// replace vars with their values in testText
for ( var k = 0 ; k < paramsArray.length ; k++ ) {
var pair = paramsArray[k];
testText = testText.replace(pair[0],pair[1]);
}
// removes all < /tr>
// in order to split on < tr>
testText = testText.replace(/<\/\s*tr[^>]*>/ig,"");
// split on <tr>
var testRows = testText.split(/<\s*tr[^>]*>/i);
return testRows;
};
IDEIncludeCommand.prototype.getIncludeDocumentBySynchronRequest = function(includeUrl) {
/**
* Prepare and do the XMLHttp Request synchronous as selenium should not continue execution meanwhile
*
* note: the XMLHttp requester is returned (instead of e.g. its text) to let the caller decide to use xml or text
*
* selenium-dependency: uses extended String from htmlutils
*
* TODO use Ajax from prototype like this:
* var sjaxRequest = new Ajax.Request(url, {asynchronous:false});
* there is discussion about getting rid of prototype.js in developer forum.
* the ajax impl in xmlutils.js is not active by default in 0.8.2
*
* #param includeUrl URI to the include-document (document has to be from the same domain)
* #return XMLHttp requester after receiving the response
*/
var url = this.prepareUrl(includeUrl);
// the xml http requester to fetch the page to include
var requester = this.newXMLHttpRequest();
if (!requester) {
throw new Error("XMLHttp requester object not initialized");
}
requester.open("GET", url, false); // synchron mode ! (we don't want selenium to go ahead)
try {
requester.send(null);
} catch(e) {
throw new Error("Error while fetching url '" + url + "' details: " + e);
}
if ( requester.status != 200 && requester.status !== 0 ) {
throw new Error("Error while fetching " + url + " server response has status = " + requester.status + ", " + requester.statusText );
}
return requester;
};
IDEIncludeCommand.prototype.prepareUrl = function(includeUrl) {
/** Construct absolute URL to get include document
* using selenium-core handling of urls (see absolutify in htmlutils.js)
*/
var prepareUrl;
// htmlSuite mode of SRC? TODO is there a better way to decide whether in SRC mode?
if (window.location.href.indexOf("selenium-server") >= 0) {
LOG.debug(IDEIncludeCommand.LOG_PREFIX + "we seem to run in SRC, do we?");
preparedUrl = absolutify(includeUrl, htmlTestRunner.controlPanel.getTestSuiteName());
} else {
preparedUrl = absolutify(includeUrl, selenium.browserbot.baseUrl);
}
LOG.debug(IDEIncludeCommand.LOG_PREFIX + "using url to get include '" + preparedUrl + "'");
return preparedUrl;
};
IDEIncludeCommand.prototype.newXMLHttpRequest = function() {
// TODO should be replaced by impl. in prototype.js or xmlextras.js
// but: there is discussion of getting rid of prototype.js
// and: currently xmlextras.js is not activated in testrunner of 0.8.2 release
var requester = 0;
var exception = '';
// see http://developer.apple.com/internet/webcontent/xmlhttpreq.html
// changed order of native and activeX to get it working with native
// xmlhttp in IE 7. credits dhwang
try {
// for IE/ActiveX
if(window.ActiveXObject) {
try {
requester = new ActiveXObject("Msxml2.XMLHTTP");
}
catch(e) {
requester = new ActiveXObject("Microsoft.XMLHTTP");
}
}
// Native XMLHttp
else if(window.XMLHttpRequest) {
requester = new XMLHttpRequest();
}
}
catch(e) {
throw new Error("Your browser has to support XMLHttpRequest in order to use include \n" + e);
}
return requester;
};
IDEIncludeCommand.prototype.splitParamStrIntoVariables = function(paramString) {
/**
* Split include Parameters-String into an 2-dim array containing Variable-Name and -Value
*
* selenium-dependency: uses extended String from htmlutils
*
* TODO: write jsunit tests - this could be easy (if there were not the new RegExp)
*
* #param includeParameters string the parameters from include call
* #return new 2-dim Array containing regExpName (to find a matching variablename) and value to be substituted for
*/
var newParamsArray = new Array();
// paramString shall contains a list of var_name=value
var paramListPattern = /([^=,]+=[^=,]*,)*([^=,]+=[^=,]*)/;
if (! paramString || paramString === "") {
return newParamsArray;
} else if (paramString.match( paramListPattern )) {
// parse parameters to fill newParamsArray
var pairs = paramString.split(",");
for ( var i = 0 ; i < pairs.length ; i++ ) {
var pair = pairs[i];
var nameValue = pair.split("=");
//rz: use String.trim from htmlutils.js of selenium to get rid of whitespace in variable-name(s)
var trimmedNameValue = new String(nameValue[0]).trim();
// the pattern to substitute is ${var_name}
var regExpName = new RegExp("\\$\\{" + trimmedNameValue + "\\}", "g");
if (nameValue.length < 3) {
newParamsArray.push(new Array(regExpName,nameValue[1]));
} else {
var varValue = new String(nameValue[1]);
for (var j = 2; j < nameValue.length; j++) {
varValue=varValue.concat("="+nameValue[j]);
}
newParamsArray.push(new Array(regExpName,varValue));
}
}
} else {
throw new Error("Bad format for parameters list : '" + paramString + "'");
}
return newParamsArray;
};
IDEIncludeCommand.prototype.doInclude = function(locator, paramString) {
// Rewrite logic for Selenium IDE by Jerry Qian
var currentSelHtmlTestcase = testCase;
var includeCmdRow = testCase.debugContext.currentCommand();
if (!includeCmdRow) {
throw new Error("IDEIncludeCommand: failed to find include-row in source testtable");
}
var paramsArray = this.splitParamStrIntoVariables(paramString);
var inclDoc = this.getIncludeDocumentBySynchronRequest(locator);
// Get an array of commands from the include text with all whitespace stripped
var includedTestCaseHtml = this.prepareTestCaseAsText(inclDoc.responseText, paramsArray);
this.injectIncludeTestCommands(locator,includeCmdRow,includedTestCaseHtml);
};
IDEIncludeCommand.prototype.injectIncludeTestCommands = function(locator,includeCmdRow, testRows) {
// Rewrite logic for Selenium IDE by Jerry Qian
var newCommands = new Array();
// skip first element as it is empty or <tbody>
for (var i = 1 ; i < testRows.length; i++) {
if(i == 1){// add BEGIN-END block
var beginCommand = new Command(IDEIncludeCommand.BEGIN_TEMPLATE,locator,"");
newCommands.push(beginCommand);
}
var newText = testRows[i];
if(newText.match(/<\s*td.*colspan=.*>(.*)<\/\s*td[^>]*>/i)){//delete comment step
continue;
}
// removes all < /td>
// in order to split on <td>
newText = newText.replace(/<\/\s*td[^>]*>\s*<\/\s*tbody[^>]*>/ig,""); //remove </tbody>first
newText = newText.replace(/<\/\s*td[^>]*>/ig,"");
var newCols = newText.split(/<\s*td[^>]*>/i);
var new_cmd,new_target,new_value;
for (var j = 1 ; j < newCols.length; j++) {//skip 0
if(j == 1) {
new_cmd = newCols[j].replace(/\s/g,"");//trim \s
}else if(j == 2) {
new_target = newCols[j].replace(/\s+$/g,"");//trim end \s
}else if(j == 3) {
new_value = newCols[j].replace(/\s+$/g,"");//trim end \s
}
}
var newCommand = new Command(new_cmd,new_target,new_value);
newCommands.push(newCommand); //correct all steps
}
var endCommand = new Command(IDEIncludeCommand.END_TEMPLATE,locator,"");
newCommands.push(endCommand);//add BEGIN-END block
var cmsBefore = testCase.commands.slice(0,testCase.debugContext.debugIndex + 1);
var cmdsBehind = testCase.commands.slice(testCase.debugContext.debugIndex + 1, testCase.commands.length);
testCase.commands = cmsBefore.concat(newCommands).concat(cmdsBehind);//Injection
// Don't inject if it appears the injection has already been done
// (i.e., if the next command is the BEGIN).
if (testCase.commands.length <= testCase.debugContext.debugIndex+1
|| beginCommand.toString() != testCase.commands[testCase.debugContext.debugIndex+1].toString())
{
// The include command cannot be the last command in the TestCase, or else
// the de-injection code in doEnd$Template$ will cause an error. So we'll
// add a simple echo if it is the last.
if (testCase.commands.length == testCase.debugContext.debugIndex+1)
{
// Using concat instead of push so that we don't trigger the TestCase's set-modified flag.
testCase.commands = testCase.commands.concat(new Command("echo", "The include command cannot be the last line in a TestCase, so this command was added. It can be left in place or removed, as desired.", "The include command cannot be the last line in a TestCase, so this command was added. It can be left in place or removed, as desired."));
}
// This is original code.
var cmsBefore = testCase.commands.slice(0,testCase.debugContext.debugIndex + 1);
var cmdsBehind = testCase.commands.slice(testCase.debugContext.debugIndex + 1, testCase.commands.length);
testCase.commands = cmsBefore.concat(newCommands).concat(cmdsBehind);//Injection
}
};
Selenium.prototype.doInclude = function(locator, paramString) {
LOG.debug(IDEIncludeCommand.LOG_PREFIX + "Version " + IDEIncludeCommand.VERSION);
var ideIncludeCommand = new IDEIncludeCommand();
ideIncludeCommand.doInclude(locator, paramString);
// If goto scripts exist then reindex the labels. goto_sel_ide.js creates an array of labels when the
// script is initialized but an included file's labels are not part of that initial read, so this function
// re-initializes that array with the included files labels (if any). If goto_sel.ide.js is not included
// it's ignored.
try {
this.initialiseLabels();
}
catch (e) {
LOG.debug("Goto Script not used.");
}
};
// Array to hold the starting position of the Begin$Template$ marker. Pushing and popping the position onto an array
// allows us to correctly handle nested includes during clean up.
var beginTemplateIndex = new Array();
// Mark the beginning of the include
Selenium.prototype.doBegin$Template$ = function(locator){
LOG.info("Begin Template " + locator + " at position " + testCase.debugContext.debugIndex);
// Add the current position to the tail of the beginTemplateIndex
beginTemplateIndex.push(testCase.debugContext.debugIndex);
};
// Clean up everything between the closest Begin$Template$ and this $End$Template$, and pop the position off the array.
Selenium.prototype.doEnd$Template$ = function(locator){
// Remove the last Begin$Template$ from the tail of the beginTemplateIndex
var currentBeginTemplateIndex = beginTemplateIndex.pop();
LOG.info("End Template " + locator + " at position " + currentBeginTemplateIndex);
// Delete the commands that we injected in injectIncludeTestCommands.
testCase.commands =
testCase.commands.slice(0,currentBeginTemplateIndex).concat(
testCase.commands.slice(testCase.debugContext.debugIndex+1, testCase.commands.length));
// Set the current command to the next one after the injected block.
testCase.debugContext.debugIndex = currentBeginTemplateIndex-1;
//Must refresh to syncup UI
editor.view.refresh();
};
datadriven.js
/************************************ DATADRIVEN EXTENSION START ********************************************/
/*
NAME:
datadriven
Licensed under Apache License v2
http://www.apache.org/licenses/LICENSE-2.0
PURPOSE:
Basic data driven testing.
Full documentation at http://wiki.openqa.org/display/SEL/datadriven
EXAMPLE USE:
The structure of your data driven test case will be;
-------------------------------------------
COMMAND |TARGET |VALUE
-------------------------------------------
loadTestData |<file path> |
while |!testdata.EOF() |
testcommand1 | |
testcommand...| |
testcommandn | |
endWhile | |
-------------------------------------------
AUTHOR:
Jonathan McBrien
jonathan#mcbrien.org
2008-10-22: v0.1: Initial version.
2009-01-16: v0.2: Updated for Firefox 3.
xmlTestData.prototype.load now uses the include extension's getIncludeDocumentBySynchronRequest method for better portability.
(Why reinvent the wheel? :) - with appreciation to the include extension's authors.)
*/
XML.serialize = function(node) {
if (typeof XMLSerializer != "undefined")
return (new XMLSerializer()).serializeToString(node) ;
else if (node.xml) return node.xml;
else throw "XML.serialize is not supported or can't serialize " + node;
}
function xmlTestData() {
this.xmlDoc = null;
this.testdata = null;
this.index = null;
}
xmlTestData.prototype.load = function(xmlloc) {
loader = new IDEIncludeCommand();
var xmlHttpReq = loader.getIncludeDocumentBySynchronRequest(xmlloc);
this.xmlDoc = xmlHttpReq.responseXML;
this.index = 0;
this.testdata = this.xmlDoc.getElementsByTagName("test");
if (this.testdata == null || this.testdata.length == 0) {
throw new Error("Test data couldn't be loaded or test data was empty.");
}
}
xmlTestData.prototype.EOF = function() {
if (this.index != null && this.index < this.testdata.length) return false;
return true;
}
xmlTestData.prototype.more = function() {
return !this.EOF();
}
xmlTestData.prototype.next = function() {
if (this.EOF()) {
LOG.error("No test data.");
return;
}
LOG.info(XML.serialize(this.testdata[this.index])); // Log should anything go wrong while testing with this data.
if (this.testdata[this.index].attributes.length != this.testdata[0].attributes.length) {
LOG.error("Inconsistent attribute length in test data.");
return;
}
for (i=0; i<this.testdata[this.index].attributes.length; i++){
if (null == this.testdata[0].getAttribute(this.testdata[this.index].attributes[i].nodeName)) {
LOG.error("Inconsistent attribute names in test data.");
return;
}
selenium.doStore(this.testdata[this.index].attributes[i].nodeValue, this.testdata[this.index].attributes[i].nodeName);
}
this.index++;
}
Selenium.prototype.testdata = null;
Selenium.prototype.doLoadTestData = function(xmlloc) {
testdata = new xmlTestData();
testdata.load(xmlloc);
};
Selenium.prototype.doNextTestData = function() {
testdata.next();
};
/************************************ DATADRIVEN EXTENSION END **********************************************/
Current solution is a SelBlocks component which allows you to do cycles according to the dataset in XML
ForXML | XMLFileName.XML
... test case steps
EndForXML
The XML should have specific structure
<testdata>
<vars storedVariable1="xxxxx" storedVariable2="yyyyy" .. storedVariableN="zzzzz" />
.. other record(s)
</testdata>
Each stored variable vill be available in test case as ${storedVariableN}.
You can produce XML by MS Excel or LibreOffice using Formulas like this one and copy it to whole table:
="<vars "&
" "&$A$1&"="""&A2&""" "&
" "&$B$1&"="""&B2&""" "&
..
" "&$X$1&"="""&X2&""" "&
"/>")
XML can be easily copypasted after each change of the dataset.
Selblocks contains the while, datadriven, goto, loop and other extensions mentioned in previous answers. You can use other functionalities of the Selblocks as conditional jumps, conditions, catch-try blocks, functions, etc. See full reference here: http://refactoror.wikia.com/wiki/Selblocks_Reference
Beware with new Selenium 3 release and Sel Core absence it is not guaranteed, that tests with Selblock addon will work in the future versions of the firefox.
You can also check this very nice blog article:
http://seleniumworks.blogspot.com/2014/01/selenium-ide-data-driven.html
This gives an explanation on how to use the needed plugins and where to download them from. It worked perfectly for me.
This answer pretty much has the same approach as the one provided by #Yevgen Ulyanenkov as I used his answer in order to find the above article. But has some more googling to it that hopefully will be helpful to someone.
I think you need to use loop I don't see your code so just check this one for selenium-ide loop If you have any more problem if so comment my answer. I can't comment into your question because reputation is not enough so. If possible please add your code into your question.

Efficient Way to do batch import XMI in Enterprise Architect

Our team are using Enterprise Architect version 10 and SVN for the repository.
Because the EAP file size is quite big (e.g. 80 MB), we exports each packages into separate XMI and stored it into SVN. The EAP file itself is committed after some milestone. The problem is to synchronize the EAP file with work from co worker during development, we need to import lots of XMI (e.g. total can be 500 files).
I know that once the EAP file is updated, we can use Package Control -> Get All Latest. Therefore this problem occurs only during parallel development.
We have used keyboard shorcuts to do the import as follow:
Ctrl+Alt+I (Import package from XMI file)
Select the file name to import
Alt+I (Import)
Enter (Yes)
Repeat step number 2 to 4 until module finished
But still, importing hundreds of file is inefficient.
I've checked that the Control Package has Batch Import/Export. The batch import/export are working when I explicitly hard-coded the XMI Filename, but the options are not available if using version control (batch import/export options are greyed).
Is there any better ways to synchronize EAP and XMI files?
There is a scripting interface in EA. You might be able to automate the import using that. I've not used it but its probably quite good.
I'm not sure I fully understand your working environment, but I have some general points that may be of interest. It might be that if you use EA in a different way (especially my first point below), the need to batch import might go away.
Multiworker
First, multiple people can work on the same EAP file at a time. The EAP file is nothing more than an Access database file, and EA uses locking to stop multiple people editing the same package at the same time. But you can comfortably have multiple people editing different packages in one EAP file at the same time. Putting the EAP file on a file share somewhere is a good way of doing it.
Inbuilt Revision Control
Secondly, EA can interact directly with SVN (and other revision control systems). See this. In short, you can setup your EAP file so that individual packages (and everything below them) is SVN controlled. You can then check out an individual package, edit it, check it back in. Or indeed you can check out the whole branch below a package (including sub packages that are themselves SVN controlled).
Underneath the hood EA is importing and exporting XMI files and checking them in and out of SVN, whilst the EAP file is always the head revision. Just like what you're doing by hand, but automated. It makes sense given that you can all use the one single EAP file. You do have to be a bit careful rolling back - links originating from objects in older versions of one package might be pointing at objects that no longer exist (but you can look at the import log errors to see if this is the case). It takes a bit of getting used to, but it works pretty well.
There's also the built in package baselining functionality - that might be all you need anyway, and works quite well especially if you're all using the same EAP file.
Bigger Database Engine
Thirdly, you don't have to have an EAP file at all. The model's database can be in any suitable database system (MySQL, SQL Server, Oracle, etc). So that gives you all sorts of options for scaling up how its used, what its like over a WAN/Internet, etc.
In short Sparx have been quite sensible about how EA can be used in a multi-worker environment, and its worth exploiting that.
I have created the EA script using JScript for the automation
Here is the script to do the export:
!INC Local Scripts.EAConstants-JScript
/*
* Script Name : Export List of SVN Packages
* Author : SDK
* Purpose : Export a package and all of its subpackages information related to version
* controlled. The exported file then can be used to automatically import
* the XMIs
* Date : 30 July 2013
* HOW TO USE : 1. Select the package that you would like to export in the Project Browser
* 2. Change the output filepath in this script if necessary.
* By default it is "D:\\EAOutput.txt"
* 3. Send the output file to your colleague who wanted to import the XMIs
*/
var f;
function main()
{
// UPDATE THE FOLLOWING OUTPUT FILE PATH IF NECESSARY
var filename = "D:\\EAOutput.txt";
var ForReading = 1, ForWriting = 2, ForAppending = 8;
Repository.EnsureOutputVisible( "Script" );
Repository.ClearOutput( "Script" );
Session.Output("Start generating output...please wait...");
var treeSelectedType = Repository.GetTreeSelectedItemType();
switch ( treeSelectedType )
{
case otPackage:
{
var fso = new ActiveXObject("Scripting.FileSystemObject");
f = fso.OpenTextFile(filename, ForWriting, true);
var selectedObject as EA.Package;
selectedObject = Repository.GetContextObject();
reportPackage(selectedObject);
loopChildPackages(selectedObject);
f.Close();
Session.Output( "Done! Check your output at " + filename);
break;
}
default:
{
Session.Prompt( "This script does not support items of this type.", promptOK );
}
}
}
function loopChildPackages(thePackage)
{
for (var j = 0 ; j < thePackage.Packages.Count; j++)
{
var child as EA.Package;
child = thePackage.Packages.GetAt(j);
reportPackage(child);
loopChildPackages(child);
}
}
function getParentPath(childPackage)
{
if (childPackage.ParentID != 0)
{
var parentPackage as EA.Package;
parentPackage = Repository.GetPackageByID(childPackage.ParentID);
return getParentPath(parentPackage) + "/" + parentPackage.Name;
}
return "";
}
function reportPackage(thePackage)
{
f.WriteLine("GUID=" + thePackage.PackageGUID + ";"
+ "NAME=" + thePackage.Name + ";"
+ "VCCFG=" + getVCCFG(thePackage) + ";"
+ "XML=" + thePackage.XMLPath + ";"
+ "PARENT=" + getParentPath(thePackage).substring(1) + ";"
);
}
function getVCCFG(thePackage)
{
if (thePackage.IsVersionControlled)
{
var array = new Array();
array = (thePackage.Flags).split(";");
for (var z = 0 ; z < array.length; z++)
{
var pos = array[z].indexOf('=');
if (pos > 0)
{
var key = array[z].substring(0, pos);
var value = array[z].substring(pos + 1);
if (key=="VCCFG")
{
return (value);
}
}
}
}
return "";
}
main();
And the script to do the import:
!INC Local Scripts.EAConstants-JScript
/*
* Script Name : Import List Of SVN Packages
* Author : SDK
* Purpose : Imports a package with all of its sub packages generated from
* "Export List Of SVN Packages" script
* Date : 01 Aug 2013
* HOW TO USE : 1. Get the output file generated by "Export List Of SVN Packages" script
* from your colleague
* 2. Get the XMIs in the SVN local copy
* 3. Change the path to the output file in this script if necessary (var filename).
* By default it is "D:\\EAOutput.txt"
* 4. Change the path to local SVN
* 5. Run the script
*/
var f;
var svnPath;
function main()
{
// CHANGE THE FOLLOWING TWO LINES ACCORDING TO YOUR INPUT AND LOCAL SVN COPY
var filename = "D:\\EAOutput.txt";
svnPath = "D:\\svn.xxx.com\\yyy\\docs\\design\\";
var ForReading = 1, ForWriting = 2, ForAppending = 8;
Repository.EnsureOutputVisible( "Script" );
Repository.ClearOutput( "Script" );
Session.Output("[INFO] Start importing packages from " + filename + ". Please wait...");
var fso = new ActiveXObject("Scripting.FileSystemObject");
f = fso.OpenTextFile(filename, ForReading);
// Read from the file and display the results.
while (!f.AtEndOfStream)
{
var r = f.ReadLine();
parseLine(r);
Session.Output("--------------------------------------------------------------------------------");
}
f.Close();
Session.Output("[INFO] Finished");
}
function parseLine(line)
{
Session.Output("[INFO] Parsing " + line);
var array = new Array();
array = (line).split(";");
var guid;
var name;
var isVersionControlled;
var xmlPath;
var parentPath;
isVersionControlled = false;
xmlPath = "";
for (var z = 0 ; z < array.length; z++)
{
var pos = array[z].indexOf('=');
if (pos > 0)
{
var key = array[z].substring(0, pos);
var value = array[z].substring(pos + 1);
if (key=="GUID") {
guid = value;
} else if (key=="NAME") {
name = value;
} else if (key=="VCCFG") {
if (value != "") {
isVersionControlled = true;
}
} else if (key=="XML") {
if (isVersionControlled) {
xmlPath = value;
}
} else if (key=="PARENT") {
parentPath = value;
}
}
}
// Quick check for target if already exist to speed up process
var targetPackage as EA.Package;
targetPackage = Repository.GetPackageByGuid(guid);
if (targetPackage != null)
{
// target exists, do not do anything
Session.Output("[DEBUG] Target package \"" + name + "\" already exist");
return;
}
var paths = new Array();
var packages = new Array(paths.Count);
for (var i = 0; i < paths.Count; i++)
{
packages[i] = null;
}
paths = (parentPath).split("/");
if (paths.Count < 2)
{
Session.Output("[INFO] Skipped root or level1");
return;
}
packages[0] = selectRoot(paths[0]);
packages[1] = selectPackage(packages[0], paths[1]);
if (packages[1] == null)
{
Session.Output("[ERROR] Cannot find " + paths[0] + "/" + paths[1] + "in Project Browser");
return;
}
for (var j = 2; j < paths.length; j++)
{
packages[j] = selectPackage(packages[j - 1], paths[j]);
if (packages[j] == null)
{
Session.Output("[DEBUG] Creating " + packages[j].Name);
// create the parent package
var parent as EA.Package;
parent = Repository.GetPackageByGuid(packages[j-1].PackageGUID);
packages[j] = parent.Packages.AddNew(paths[j], "");
packages[j].Update();
parent.Update();
parent.Packages.Refresh();
break;
}
}
// Check if name (package to import) already exist or not
var targetPackage = selectPackage(packages[paths.length - 1], name);
if (targetPackage == null)
{
if (xmlPath == "")
{
Session.Output("[DEBUG] Creating " + name);
// The package is not SVN controlled
var newPackage as EA.Package;
newPackage = packages[paths.length - 1].Packages.AddNew(name,"");
Session.Output("New GUID = " + newPackage.PackageGUID);
newPackage.Update();
packages[paths.length - 1].Update();
packages[paths.length - 1].Packages.Refresh();
}
else
{
// The package is not SVN controlled
Session.Output("[DEBUG] Need to import: " + svnPath + xmlPath);
var project as EA.Project;
project = Repository.GetProjectInterface;
var result;
Session.Output("GUID = " + packages[paths.length - 1].PackageGUID);
Session.Output("GUID XML = " + project.GUIDtoXML(packages[paths.length - 1].PackageGUID));
Session.Output("XMI file = " + svnPath + xmlPath);
result = project.ImportPackageXMI(project.GUIDtoXML(packages[paths.length - 1].PackageGUID), svnPath + xmlPath, 1, 0);
Session.Output(result);
packages[paths.length - 1].Update();
packages[paths.length - 1].Packages.Refresh();
}
}
else
{
// target exists, do not do anything
Session.Output("[DEBUG] Target package \"" + name + "\" already exist");
}
}
function selectPackage(thePackage, childName)
{
var childPackage as EA.Package;
childPackage = null;
if (thePackage == null)
return null;
for (var i = 0; i < thePackage.Packages.Count; i++)
{
childPackage = thePackage.Packages.GetAt(i);
if (childPackage.Name == childName)
{
Session.Output("[DEBUG] Found " + childName);
return childPackage;
}
}
Session.Output("[DEBUG] Cannot find " + childName);
return null;
}
function selectRoot(rootName)
{
for (var y = 0; y < Repository.Models.Count; y++)
{
root = Repository.Models.GetAt(y);
if (root.Name == rootName)
{
return root;
}
}
return null;
}
main();