summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Unknown <t-espave@A3479886.redmond.corp.microsoft.com>2011-07-15 11:11:46 -0700
committerGravatar Unknown <t-espave@A3479886.redmond.corp.microsoft.com>2011-07-15 11:11:46 -0700
commit7dea3ce2cd43af0f3a7efc6ef57136d5a2fd8099 (patch)
tree869e979464433fa5c208d7f05e73166f42836b74
parent4c0b3cd19f6259d4b7f644497212f639c1e07706 (diff)
initial page detection and init
-rw-r--r--BCT/BytecodeTranslator/Phone/PhoneCodeHelper.cs9
-rw-r--r--BCT/BytecodeTranslator/Phone/PhoneNavigationTraverser.cs15
-rw-r--r--BCT/BytecodeTranslator/Program.cs5
-rw-r--r--BCT/PhoneControlsExtractor/PhoneControlsExtractor.py25
-rw-r--r--BCT/TranslationPlugins/PhoneControlsPlugin.cs25
5 files changed, 62 insertions, 17 deletions
diff --git a/BCT/BytecodeTranslator/Phone/PhoneCodeHelper.cs b/BCT/BytecodeTranslator/Phone/PhoneCodeHelper.cs
index 411fc819..74ad2140 100644
--- a/BCT/BytecodeTranslator/Phone/PhoneCodeHelper.cs
+++ b/BCT/BytecodeTranslator/Phone/PhoneCodeHelper.cs
@@ -126,8 +126,13 @@ namespace BytecodeTranslator.Phone {
/// <param name="uri"></param>
/// <returns></returns>
public static string getURIBase(string uri) {
- // TODO
- return uri;
+ // I need to build an absolute URI just to call getComponents() ...
+ Uri mockBaseUri = new Uri("mock://mock/", UriKind.RelativeOrAbsolute);
+ Uri realUri = new Uri(mockBaseUri, uri);
+
+ string str= realUri.GetComponents(UriComponents.Path|UriComponents.StrongAuthority|UriComponents.Scheme, UriFormat.UriEscaped);
+ Uri mockStrippedUri = new Uri(str);
+ return mockBaseUri.MakeRelativeUri(mockStrippedUri).ToString();
}
}
}
diff --git a/BCT/BytecodeTranslator/Phone/PhoneNavigationTraverser.cs b/BCT/BytecodeTranslator/Phone/PhoneNavigationTraverser.cs
index 5f08f1c7..b702e78b 100644
--- a/BCT/BytecodeTranslator/Phone/PhoneNavigationTraverser.cs
+++ b/BCT/BytecodeTranslator/Phone/PhoneNavigationTraverser.cs
@@ -4,18 +4,21 @@ using System.Linq;
using System.Text;
using Microsoft.Cci;
using Microsoft.Cci.MutableCodeModel;
+using TranslationPlugins;
namespace BytecodeTranslator.Phone {
public class PhoneNavigationCodeTraverser : BaseCodeTraverser {
private MetadataReaderHost host;
private ITypeReference navigationSvcType;
private ITypeReference typeTraversed;
+ private PhoneControlsPlugin phonePlugin;
private static readonly string[] NAV_CALLS = { "GoBack", "GoForward", "Navigate", "StopLoading" };
- public PhoneNavigationCodeTraverser(MetadataReaderHost host, ITypeReference typeTraversed) : base() {
+ public PhoneNavigationCodeTraverser(PhoneControlsPlugin plugin, MetadataReaderHost host, ITypeReference typeTraversed) : base() {
this.host = host;
this.typeTraversed = typeTraversed;
+ this.phonePlugin = plugin;
Microsoft.Cci.Immutable.PlatformType platform = host.PlatformType as Microsoft.Cci.Immutable.PlatformType;
// TODO obtain version, culture and signature data dynamically
@@ -33,7 +36,7 @@ namespace BytecodeTranslator.Phone {
if (method.IsConstructor && PhoneCodeHelper.isPhoneApplicationClass(typeTraversed, host)) {
// TODO initialize current navigation URI to mainpage, using a placeholder for now.
// TODO BUG doing this is generating a fresh variable definition somewhere that the BCT then translates into two different (identical) declarations
- string URI_placeholder="URI_PLACEHOLDER";
+ string mainPageUri = phonePlugin.getMainPageXAML();
SourceMethodBody sourceBody = method.Body as SourceMethodBody;
if (sourceBody != null) {
BlockStatement bodyBlock = sourceBody.Block as BlockStatement;
@@ -41,7 +44,7 @@ namespace BytecodeTranslator.Phone {
Assignment uriInitAssign = new Assignment() {
Source = new CompileTimeConstant() {
Type = host.PlatformType.SystemString,
- Value = URI_placeholder,
+ Value = mainPageUri,
},
Type = host.PlatformType.SystemString,
Target = new TargetExpression() {
@@ -230,10 +233,12 @@ namespace BytecodeTranslator.Phone {
public class PhoneNavigationMetadataTraverser : BaseMetadataTraverser {
private MetadataReaderHost host;
private ITypeDefinition typeBeingTraversed;
+ private PhoneControlsPlugin phonePlugin;
- public PhoneNavigationMetadataTraverser(MetadataReaderHost host)
+ public PhoneNavigationMetadataTraverser(PhoneControlsPlugin plugin, MetadataReaderHost host)
: base() {
this.host = host;
+ this.phonePlugin = plugin;
}
public override void Visit(IModule module) {
@@ -267,7 +272,7 @@ namespace BytecodeTranslator.Phone {
// TODO same here. Are there specific methods (and ways to identfy those) that can perform navigation?
public override void Visit(IMethodDefinition method) {
- PhoneNavigationCodeTraverser codeTraverser = new PhoneNavigationCodeTraverser(host, typeBeingTraversed);
+ PhoneNavigationCodeTraverser codeTraverser = new PhoneNavigationCodeTraverser(phonePlugin, host, typeBeingTraversed);
codeTraverser.Visit(method);
}
diff --git a/BCT/BytecodeTranslator/Program.cs b/BCT/BytecodeTranslator/Program.cs
index 0867de9f..14d0a466 100644
--- a/BCT/BytecodeTranslator/Program.cs
+++ b/BCT/BytecodeTranslator/Program.cs
@@ -177,9 +177,10 @@ namespace BytecodeTranslator {
var primaryModule = modules[0];
if (phoneControlsConfigFile != null && phoneControlsConfigFile != "") {
- PhoneInitializationMetadataTraverser initTr = new PhoneInitializationMetadataTraverser(new PhoneControlsPlugin(phoneControlsConfigFile), host);
+ PhoneControlsPlugin phonePlugin = new PhoneControlsPlugin(phoneControlsConfigFile);
+ PhoneInitializationMetadataTraverser initTr = new PhoneInitializationMetadataTraverser(phonePlugin, host);
initTr.InjectPhoneCodeAssemblies(modules);
- PhoneNavigationMetadataTraverser navTr = new PhoneNavigationMetadataTraverser(host);
+ PhoneNavigationMetadataTraverser navTr = new PhoneNavigationMetadataTraverser(phonePlugin, host);
navTr.InjectPhoneCodeAssemblies(modules);
}
diff --git a/BCT/PhoneControlsExtractor/PhoneControlsExtractor.py b/BCT/PhoneControlsExtractor/PhoneControlsExtractor.py
index 8ca29036..89cc0c31 100644
--- a/BCT/PhoneControlsExtractor/PhoneControlsExtractor.py
+++ b/BCT/PhoneControlsExtractor/PhoneControlsExtractor.py
@@ -13,6 +13,7 @@ CONTROL_NAMES= ["Button", "CheckBox", "RadioButton"]
CONTAINER_CONTROL_NAMES= ["Canvas", "Grid", "StackPanel"]
staticControlsMap= {}
+mainPageXAML= None
def showUsage():
print "PhoneControlsExtractor -- extract control information from phone application pages"
@@ -90,10 +91,10 @@ def extractPhoneControlsFromPage(pageXAML):
pageFile.close()
removeBlankElements(pageFileXML)
controls= getControlNodes(pageFileXML)
+ ownerPage = None
for control in controls:
- ownerPage=""
parent= control
- while not parent == None:
+ while not parent == None and ownerPage == None:
if parent.localName == "PhoneApplicationPage":
ownerPage= parent.getAttribute("x:Class")
parent= parent.parentNode
@@ -102,8 +103,9 @@ def extractPhoneControlsFromPage(pageXAML):
def outputPhoneControls(outputFileName):
outputFile= open(outputFileName, "w")
- # Output format is one line per
+ # Output format is first line containing only the main page, and then one line per
# <pageClassName>,<page.xaml file>,<controlClassName>,<controlName (as in field name)>,<IsEnabledValue>,<VisibilityValue>,<ClickValue>,<CheckedValue>,<UncheckedValue>
+ outputFile.write(mainPageXAML + "\n")
for page in staticControlsMap.keys():
for control in staticControlsMap[page]:
isEnabled= control["IsEnabled"]
@@ -116,12 +118,23 @@ def outputPhoneControls(outputFileName):
outputFile.close()
+def getMainPageXAMLFromManifest(filename):
+ file= open(filename, "r");
+ manifest= minidom.parse(file)
+ file.close()
+ # interesting XPath location /App/Tasks/DefaultTask/@NavigationPage
+ return manifest.getElementsByTagName("DefaultTask")[0].getAttribute("NavigationPage")
+
def extractPhoneControls(sourceDir):
- fileList= [os.path.join(sourceDir, fileName) for fileName in os.listdir(sourceDir) if os.path.splitext(fileName)[1] == ".xaml"]
+ global mainPageXAML
+ fileList= [os.path.join(sourceDir, fileName) for fileName in os.listdir(sourceDir) if os.path.splitext(fileName)[1] == ".xaml" or os.path.splitext(fileName)[1] == ".xml"]
for fileName in fileList:
- extractPhoneControlsFromPage(fileName)
+ if os.path.splitext(fileName)[1] == ".xml" and os.path.splitext(os.path.split(fileName)[1])[0].lower() == "wmappmanifest":
+ mainPageXAML= getMainPageXAMLFromManifest(fileName)
+ break
- # TODO dump controls into a config file that can be passed to BCT
+ for fileName in fileList:
+ extractPhoneControlsFromPage(fileName)
def main():
pagesDir= ""
diff --git a/BCT/TranslationPlugins/PhoneControlsPlugin.cs b/BCT/TranslationPlugins/PhoneControlsPlugin.cs
index ac017d38..8c7294ec 100644
--- a/BCT/TranslationPlugins/PhoneControlsPlugin.cs
+++ b/BCT/TranslationPlugins/PhoneControlsPlugin.cs
@@ -65,8 +65,9 @@ namespace TranslationPlugins {
controlsInfo = new Dictionary<string, ControlInfoStructure>();
}
- public string PageClassName;
- public string PageXAML;
+ public string PageClassName { get; set; }
+ public string PageXAML { get; set; }
+ public bool IsMainPage { get; set; }
private IDictionary<string, ControlInfoStructure> controlsInfo;
public ControlInfoStructure getControlInfo(string controlName) {
@@ -128,6 +129,20 @@ namespace TranslationPlugins {
fileStream.Close();
}
+ public string getMainPageXAML() {
+ KeyValuePair<string, PageStructure> entry= pageStructureInfo.FirstOrDefault(keyValue => keyValue.Value.IsMainPage);
+ return entry.Value.PageXAML;
+ }
+
+ private void setPageAsMainPage(string pageXAML) {
+ KeyValuePair<string,PageStructure> mainPageClass= pageStructureInfo.FirstOrDefault(keyValue => keyValue.Value.PageXAML == pageXAML);
+ if (mainPageClass.Equals(default(KeyValuePair<string, PageStructure>))) {
+ // do nothing. Pre is page was already parsed
+ } else {
+ mainPageClass.Value.IsMainPage = true;
+ }
+ }
+
private void LoadControlStructure(StreamReader configStream) {
// TODO it would be nice to have some kind of dynamic definition of config format
// TODO for now remember that config format is CSV
@@ -144,6 +159,10 @@ namespace TranslationPlugins {
PageStructure pageStr;
ControlInfoStructure controlInfoStr;
+ // first line just states the main page xaml
+ string mainPage = configLine.Trim();
+ configLine = configStream.ReadLine();
+
while (configLine != null) {
inputLine = configLine.Split(',');
@@ -166,6 +185,7 @@ namespace TranslationPlugins {
pageStr = new PageStructure();
pageStr.PageClassName = pageClass;
pageStr.PageXAML = pageXAML;
+ pageStr.IsMainPage = false;
}
controlInfoStr= pageStr.getControlInfo(controlName);
@@ -184,6 +204,7 @@ namespace TranslationPlugins {
pageStructureInfo[pageClass] = pageStr;
configLine = configStream.ReadLine();
+ setPageAsMainPage(mainPage);
}
} catch (Exception) {
// TODO log, I don't want to terminate BCT because of this