Hello!

I'd like to enable remote rules in the client engine. Currently this
feature is turned of in
src/syncapps/clientEngine_custom/product_options.h.

This is not normally useful in clients, but in SyncEvolution we could
use it to encode items slightly differently for the SyncML server and
for Evolution [1], without specifying (and maintaining) two entirely
different profiles:
      * add a "remote rule name" parameter to MAKETEXTWITHPROFILE() and
        PARSETEXTWITHPROFILE()
      * use that name to set fAppliedRemoteRuleP
      * in our XML config, check for that remote rule on specific
        properties

I have the code basically ready (see below), but when testing with a
specific problem, I wasn't entirely sure whether the remote rules really
would help: suppose I want to encode the manager name as
X-EVOLUTION-MANAGER when talking to Evolution and as X-MANAGER otherwise
[2].

How can I configure that, assuming that the current rule is "EVOLUTION"?

I suspect that this won't work:
        <property name="X-EVOLUTION-MANAGER" suppressempty="yes" 
rule="EVOLUTION">
          <value field="MANAGER" show="yes"/>
        </property>
        <property name="X-MANAGER" suppressempty="yes" rule="other">
          <value field="MANAGER" show="yes"/>
        </property>

When encoding for EVOLUTION, both rules will be active, the first one
because the rule matches, the second because no other rule matched first
in the group of properties with name "X-MANAGER" (because there is no
other). Correct?

How about this:
        <property name="X-EVOLUTION-MANAGER" suppressempty="yes" 
rule="EVOLUTION">
          <value field="MANAGER" show="yes"/>
        </property>
        <property name="X-MANAGER" suppressempty="yes" rule="EVOLUTION"/>
        <property name="X-MANAGER" suppressempty="yes" rule="other">
          <value field="MANAGER" show="yes"/>
        </property>

Is that valid? It seems to be accepted, but somehow X-EVOLUTION-MANAGER
is always chosen. Ah, <remoterule name="EVOLUTION"/> means the rule is
always active. It works with:
    <remoterule name="EVOLUTION">
      <deviceid>foobar</deviceid>
    </remoterule>

Is there a better way that avoids the dummy property entry?

What about adding support for:
        <property name="X-MANAGER" suppressempty="yes" rule="^EVOLUTION">
          <value field="MANAGER" show="yes"/>
        </property>

The drawback is that multiple not clauses are impossible, but in this
case it would work nicely.

Regarding the code patches (attached for review), do
MAKETEXTWITHPROFILE() and PARSETEXTWITHPROFILE() really have an
*optional* mode parameter as the comment implies? I bet it will crash if
the parameter is not passed because getLocalVar() returns NULL for it.

But perhaps I'm misunderstanding the macro definition. Does the patch
make sense as it is right now?

Regarding enabling the feature: I'm modifying the default
target_options.h. It would be nicer to make that dependent on configure
[3] so that we can enable it when compiling for SyncEvolution.

[1] http://bugzilla.moblin.org/show_bug.cgi?id=2417
[2] http://bugzilla.moblin.org/show_bug.cgi?id=2418
[3] http://bugzilla.moblin.org/show_bug.cgi?id=3471

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.

>From e14f54d14e171bc40985970f3b56d5b334fd57ad Mon Sep 17 00:00:00 2001
From: Patrick Ohly <patrick.o...@intel.com>
Date: Tue, 23 Jun 2009 22:08:54 +0200
Subject: [PATCH 1/2] compile configuration: enable remote rules in client engine

The intention is to use MAKETEXTWITHPROFILE() and PARSETEXTWITHPROFILE()
with a slightly different MIME profile than on the server side. Instead
of defining two different profiles which only differ in some minor aspect,
remote rules could be used to enable/disable certain properties.
---
 .../clientEngine_opensource_linux/target_options.h |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/src/Targets/ReleasedProducts/clientEngine_opensource_linux/target_options.h b/src/Targets/ReleasedProducts/clientEngine_opensource_linux/target_options.h
index 10337b3..d6121f3 100755
--- a/src/Targets/ReleasedProducts/clientEngine_opensource_linux/target_options.h
+++ b/src/Targets/ReleasedProducts/clientEngine_opensource_linux/target_options.h
@@ -192,6 +192,7 @@
 // - if defined, code for incoming and outgoing SyncML dumping into (WB)XML logfiles is included
 #define MSGDUMP 1
 
-
+// - enable support for remote rules, despite being a client
+#undef NO_REMOTE_RULES
 
 /* eof */
-- 
1.6.2

>From f73c509ff8e09c14f5fc0255f17c5ae3b62d6d3d Mon Sep 17 00:00:00 2001
From: Patrick Ohly <patrick.o...@intel.com>
Date: Tue, 23 Jun 2009 22:47:23 +0200
Subject: [PATCH 2/2] MAKE/PARSETEXTWITHPROFILE: added remote rule name parameter

If not empty, the remote rule name is used to activate a specific
remote rule while using the profile. Otherwise the profile
is applied without any active rule, as before.
---
 src/sysync/mimedirprofile.cpp |   12 +++++++++++-
 src/sysync/mimedirprofile.h   |    3 +++
 src/sysync/multifielditem.h   |    4 ++++
 src/sysync/scriptcontext.cpp  |   30 +++++++++++++++++++++++++-----
 4 files changed, 43 insertions(+), 6 deletions(-)

diff --git a/src/sysync/mimedirprofile.cpp b/src/sysync/mimedirprofile.cpp
index 47566f8..5fb18b1 100644
--- a/src/sysync/mimedirprofile.cpp
+++ b/src/sysync/mimedirprofile.cpp
@@ -5000,7 +5000,17 @@ void TMimeDirProfileHandler::setProfileMode(sInt32 aMode)
   }
 } // TMimeDirProfileHandler::setProfileMode
 
-
+void TMimeDirProfileHandler::setRemoteRule(const string &aRemoteRuleName)
+{
+  TSessionConfig *scP = getSession()->getSessionConfig();
+  TRemoteRulesList::iterator pos;
+  for(pos=scP->fRemoteRulesList.begin();pos!=scP->fRemoteRulesList.end();pos++) {
+    if((*pos)->fElementName == aRemoteRuleName) {
+      fAppliedRemoteRuleP = *pos;
+      break;
+    }
+  }
+} // TMimeDirProfileHandler::setRemoteRule
 
 // - check mode
 bool TMimeDirProfileHandler::mimeModeMatch(TMimeDirMode aMimeMode)
diff --git a/src/sysync/mimedirprofile.h b/src/sysync/mimedirprofile.h
index f39dc4f..422a3b2 100755
--- a/src/sysync/mimedirprofile.h
+++ b/src/sysync/mimedirprofile.h
@@ -458,6 +458,9 @@ public:
   // set profile options
   // - mode (for those profiles that have more than one, like MIME-DIR's old/standard)
   virtual void setProfileMode(sInt32 aMode);
+#ifndef NO_REMOTE_RULES
+  virtual void setRemoteRule(const string &aRemoteRuleName);
+#endif
   // generate Text Data (includes header and footer)
   virtual void generateText(TMultiFieldItem &aItem, string &aString);
   // parse Data item (includes header and footer)
diff --git a/src/sysync/multifielditem.h b/src/sysync/multifielditem.h
index 1b66042..b60c2b6 100755
--- a/src/sysync/multifielditem.h
+++ b/src/sysync/multifielditem.h
@@ -166,6 +166,10 @@ public:
   // set profile options
   // - mode (for those profiles that have more than one, like MIME-DIR's old/standard)
   virtual void setProfileMode(sInt32 aMode) { /* nop here */ };
+#ifndef NO_REMOTE_RULES
+  // - choose remote rule by name, true if found
+  virtual void setRemoteRule(const string &aRemoteRuleName) { /* nop here */ }
+#endif
   // set related datastore (NULL for independent use e.g. from script functions)
   void setRelatedDatastore(TLocalEngineDS *aRelatedDatastoreP) { fRelatedDatastoreP = aRelatedDatastoreP; };
   // generate Text Data
diff --git a/src/sysync/scriptcontext.cpp b/src/sysync/scriptcontext.cpp
index ceee972..2c5ba37 100755
--- a/src/sysync/scriptcontext.cpp
+++ b/src/sysync/scriptcontext.cpp
@@ -1985,7 +1985,7 @@ public:
   }
 
 
-  // integer PARSETEXTWITHPROFILE(string textformat, string profileName [, int mode])
+  // integer PARSETEXTWITHPROFILE(string textformat, string profileName [, int mode = 0 = default [, string remoteRuleName = "" = other]])
   static void func_ParseTextWithProfile(TItemField *&aTermP, TScriptContext *aFuncContextP)
   {
   	bool ok = false;
@@ -1999,8 +1999,19 @@ public:
       if (profileHandlerP) {
       	// now we can convert
         // - set the mode code (none = 0 = default)
+        // TODO? Shouldn't this check whether arg #2 was passed at all? If not,
+        // the code will segfault when trying to call getAsInteger()
         profileHandlerP->setProfileMode(aFuncContextP->getLocalVar(2)->getAsInteger());
-  			profileHandlerP->setRelatedDatastore(NULL); // no datastore in particular is related
+        profileHandlerP->setRelatedDatastore(NULL); // no datastore in particular is related
+#ifndef NO_REMOTE_RULES
+        // - try to find remote rule
+        TItemField *field = aFuncContextP->getLocalVar(3);
+        if (field) {
+          field->getAsString(s);
+          if (!s.empty())
+            profileHandlerP->setRemoteRule(s);
+        }
+#endif
         // - convert
 	    	aFuncContextP->getLocalVar(0)->getAsString(s);
         ok = profileHandlerP->parseText(s.c_str(), s.size(), *itemP);
@@ -2012,7 +2023,7 @@ public:
   } // func_ParseTextWithProfile
 
 
-  // string MAKETEXTWITHPROFILE(string profileName [, int mode])
+  // string MAKETEXTWITHPROFILE(string profileName [, int mode [, string remoteRuleName = "" = other] ])
   static void func_MakeTextWithProfile(TItemField *&aTermP, TScriptContext *aFuncContextP)
   {
     if (aFuncContextP->fParentContextP) {
@@ -2027,6 +2038,15 @@ public:
         // - set the mode code (none = 0 = default)
         profileHandlerP->setProfileMode(aFuncContextP->getLocalVar(1)->getAsInteger());
         profileHandlerP->setRelatedDatastore(NULL); // no datastore in particular is related
+#ifndef NO_REMOTE_RULES
+        // - try to find remote rule
+        TItemField *field = aFuncContextP->getLocalVar(2);
+        if (field) {
+          field->getAsString(s);
+          if (!s.empty())
+            profileHandlerP->setRemoteRule(s);
+        }
+#endif
         // - convert, after clearing the string (some generateText() implementations
         // append instead of overwriting)
         s = "";
@@ -2174,8 +2194,8 @@ const TBuiltInFuncDef BuiltInFuncDefs[] = {
   { "PARSE_RRULE", TBuiltinStdFuncs::func_Parse_RRULE, fty_integer, 8, param_Parse_RRULE },
   { "PARSEEMAILSPEC", TBuiltinStdFuncs::func_ParseEmailSpec, fty_integer, 3, param_parseEmailSpec },
   { "MAKEEMAILSPEC", TBuiltinStdFuncs::func_MakeEmailSpec, fty_string, 2, param_makeEmailSpec },
-  { "PARSETEXTWITHPROFILE", TBuiltinStdFuncs::func_ParseTextWithProfile, fty_integer, 3, param_parseTextWithProfile },
-  { "MAKETEXTWITHPROFILE", TBuiltinStdFuncs::func_MakeTextWithProfile, fty_string, 2, param_makeTextWithProfile },
+  { "PARSETEXTWITHPROFILE", TBuiltinStdFuncs::func_ParseTextWithProfile, fty_integer, 4, param_parseTextWithProfile },
+  { "MAKETEXTWITHPROFILE", TBuiltinStdFuncs::func_MakeTextWithProfile, fty_string, 3, param_makeTextWithProfile },
   { "SYNCMLVERS", TBuiltinStdFuncs::func_SyncMLVers, fty_string, 0, NULL },
   { "ALLDAYCOUNT", TBuiltinStdFuncs::func_AlldayCount, fty_integer, 4, param_AlldayCount },
   { "MAKEALLDAY", TBuiltinStdFuncs::func_MakeAllday, fty_integer, 3, param_MakeAllday },
-- 
1.6.2

_______________________________________________
SyncEvolution mailing list
SyncEvolution@moblin.org
https://lists.moblin.org/mailman/listinfo/syncevolution

Reply via email to