Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7c3e18c5 authored by Daisuke Miyakawa's avatar Daisuke Miyakawa
Browse files

resolved conflicts w/ 842a1f4b merge....

parent e249059a
Loading
Loading
Loading
Loading
+69 −7
Original line number Original line Diff line number Diff line
@@ -388,8 +388,32 @@ public abstract class AbstractSyncableContentProvider extends SyncableContentPro
        return completed;
        return completed;
    }
    }


    public ContentProviderResult[] applyBatch(ContentProviderOperation[] operations)
    /**
            throws OperationApplicationException {
     * <p>
     * Call mOpenHelper.getWritableDatabase() and mDb.beginTransaction().
     * {@link #endTransaction} MUST be called after calling this method.
     * Those methods should be used like this:
     * </p>
     *
     * <pre class="prettyprint">
     * boolean successful = false;
     * if (!beginTransaction()) {
     *     return;
     * }
     * try {
     *     // Do something related to mDb
     *     successful = true;
     *     return ret;
     * } finally {
     *     endTransaction(successful);
     * }
     * </pre>
     *
     * @hide This method should be used only when {@link #applyBatch} is not enough and must be
     * used with {@link #endTransaction}.
     * e.g. If returned value has to be used during one transaction, this method might be useful.
     */
    public final void beginBatch() {
        // initialize if this is the first time this thread has applied a batch
        // initialize if this is the first time this thread has applied a batch
        if (mApplyingBatch.get() == null) {
        if (mApplyingBatch.get() == null) {
            mApplyingBatch.set(false);
            mApplyingBatch.set(false);
@@ -400,12 +424,36 @@ public abstract class AbstractSyncableContentProvider extends SyncableContentPro
            throw new IllegalStateException(
            throw new IllegalStateException(
                    "applyBatch is not reentrant but mApplyingBatch is already set");
                    "applyBatch is not reentrant but mApplyingBatch is already set");
        }
        }
        getDatabase().beginTransaction();
        SQLiteDatabase db = getDatabase();
        db.beginTransaction();
        boolean successful = false;
        try {
        try {
            mApplyingBatch.set(true);
            mApplyingBatch.set(true);
            ContentProviderResult[] results = super.applyBatch(operations);
            successful = true;
            getDatabase().setTransactionSuccessful();
        } finally {
            return results;
            if (!successful) {
                // Something unexpected happened. We must call endTransaction() at least.
                db.endTransaction();
            }
        }
    }

    /**
     * <p>
     * Call mDb.endTransaction(). If successful is true, try to call
     * mDb.setTransactionSuccessful() before calling mDb.endTransaction().
     * This method MUST be used with {@link #beginBatch()}.
     * </p>
     *
     * @hide This method must be used with {@link #beginTransaction}
     */
    public final void endBatch(boolean successful) {
        try {
            if (successful) {
                // setTransactionSuccessful() must be called just once during opening the
                // transaction.
                mDb.setTransactionSuccessful();
            }
        } finally {
        } finally {
            mApplyingBatch.set(false);
            mApplyingBatch.set(false);
            getDatabase().endTransaction();
            getDatabase().endTransaction();
@@ -413,6 +461,20 @@ public abstract class AbstractSyncableContentProvider extends SyncableContentPro
                getContext().getContentResolver().notifyChange(url, null /* observer */,
                getContext().getContentResolver().notifyChange(url, null /* observer */,
                        changeRequiresLocalSync(url));
                        changeRequiresLocalSync(url));
            }
            }
            mDb.endTransaction();
        }
    }

    public ContentProviderResult[] applyBatch(ContentProviderOperation[] operations)
            throws OperationApplicationException {
        boolean successful = false;
        beginBatch();
        try {
            ContentProviderResult[] results = super.applyBatch(operations);
            successful = true;
            return results;
        } finally {
            endBatch(successful);
        }
        }
    }
    }


+11 −0
Original line number Original line Diff line number Diff line
@@ -889,6 +889,17 @@ public class Contacts {
        public static final int TYPE_WORK = 2;
        public static final int TYPE_WORK = 2;
        public static final int TYPE_OTHER = 3;
        public static final int TYPE_OTHER = 3;


        /**
         * @hide This is temporal. TYPE_MOBILE should be added to TYPE in the future.
         */
        public static final int MOBILE_EMAIL_TYPE_INDEX = 2;

        /**
         * @hide This is temporal. TYPE_MOBILE should be added to TYPE in the future.
         * This is not "mobile" but "CELL" since vCard uses it for identifying mobile phone.
         */
        public static final String MOBILE_EMAIL_TYPE_NAME = "_AUTO_CELL";

        /**
        /**
         * The user defined label for the the contact method.
         * The user defined label for the the contact method.
         * <P>Type: TEXT</P>
         * <P>Type: TEXT</P>
+180 −14
Original line number Original line Diff line number Diff line
@@ -17,12 +17,16 @@
package android.syncml.pim;
package android.syncml.pim;


import android.content.ContentValues;
import android.content.ContentValues;
import android.util.Log;


import org.apache.commons.codec.binary.Base64;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Arrays;
import java.util.HashSet;
import java.util.HashSet;
import java.util.List;
import java.util.List;
import java.util.Set;
import java.util.Set;
import java.util.Map.Entry;
import java.util.regex.Pattern;


public class PropertyNode {
public class PropertyNode {


@@ -52,7 +56,9 @@ public class PropertyNode {
    public Set<String> propGroupSet;
    public Set<String> propGroupSet;
    
    
    public PropertyNode() {
    public PropertyNode() {
        propName = "";
        propValue = "";
        propValue = "";
        propValue_vector = new ArrayList<String>();
        paramMap = new ContentValues();
        paramMap = new ContentValues();
        paramMap_TYPE = new HashSet<String>();
        paramMap_TYPE = new HashSet<String>();
        propGroupSet = new HashSet<String>();
        propGroupSet = new HashSet<String>();
@@ -62,13 +68,21 @@ public class PropertyNode {
            String propName, String propValue, List<String> propValue_vector,
            String propName, String propValue, List<String> propValue_vector,
            byte[] propValue_bytes, ContentValues paramMap, Set<String> paramMap_TYPE,
            byte[] propValue_bytes, ContentValues paramMap, Set<String> paramMap_TYPE,
            Set<String> propGroupSet) {
            Set<String> propGroupSet) {
        if (propName != null) {
            this.propName = propName;
            this.propName = propName;
        } else {
            this.propName = "";
        }
        if (propValue != null) {
        if (propValue != null) {
            this.propValue = propValue;
            this.propValue = propValue;
        } else {
        } else {
            this.propValue = "";
            this.propValue = "";
        }
        }
        if (propValue_vector != null) {
            this.propValue_vector = propValue_vector;
            this.propValue_vector = propValue_vector;
        } else {
            this.propValue_vector = new ArrayList<String>();
        }
        this.propValue_bytes = propValue_bytes;
        this.propValue_bytes = propValue_bytes;
        if (paramMap != null) {
        if (paramMap != null) {
            this.paramMap = paramMap;
            this.paramMap = paramMap;
@@ -117,17 +131,9 @@ public class PropertyNode {
            // decoded by BASE64 or QUOTED-PRINTABLE. When the size of propValue_vector
            // decoded by BASE64 or QUOTED-PRINTABLE. When the size of propValue_vector
            // is 1, the encoded value is stored in propValue, so we do not have to
            // is 1, the encoded value is stored in propValue, so we do not have to
            // check it.
            // check it.
            if (propValue_vector != null) {
                // Log.d("@@@", "===" + propValue_vector + ", " + node.propValue_vector);
            return (propValue_vector.equals(node.propValue_vector) ||
            return (propValue_vector.equals(node.propValue_vector) ||
                        (propValue_vector.size() == 1));
                    propValue_vector.size() == 1 ||
            } else if (node.propValue_vector != null) {
                    node.propValue_vector.size() == 1);
                // Log.d("@@@", "===" + propValue_vector + ", " + node.propValue_vector);
                return (node.propValue_vector.equals(propValue_vector) ||
                        (node.propValue_vector.size() == 1));
            } else {
                return true;
            }
        }
        }
    }
    }
    
    
@@ -154,4 +160,164 @@ public class PropertyNode {
        builder.append(propValue);
        builder.append(propValue);
        return builder.toString();
        return builder.toString();
    }
    }
    
    /**
     * Encode this object into a string which can be decoded. 
     */
    public String encode() {
        // PropertyNode#toString() is for reading, not for parsing in the future.
        // We construct appropriate String here.
        StringBuilder builder = new StringBuilder();
        if (propName.length() > 0) {
            builder.append("propName:[");
            builder.append(propName);
            builder.append("],");
        }
        int size = propGroupSet.size();
        if (size > 0) {
            Set<String> set = propGroupSet;
            builder.append("propGroup:[");
            int i = 0;
            for (String group : set) {
                // We do not need to double quote groups.
                // group        = 1*(ALPHA / DIGIT / "-")
                builder.append(group);
                if (i < size - 1) {
                    builder.append(",");
                }
                i++;
            }
            builder.append("],");
        }

        if (paramMap.size() > 0 || paramMap_TYPE.size() > 0) {
            ContentValues values = paramMap;
            builder.append("paramMap:[");
            size = paramMap.size(); 
            int i = 0;
            for (Entry<String, Object> entry : values.valueSet()) {
                // Assuming param-key does not contain NON-ASCII nor symbols.
                //
                // According to vCard 3.0:
                // param-name   = iana-token / x-name
                builder.append(entry.getKey());

                // param-value may contain any value including NON-ASCIIs.
                // We use the following replacing rule.
                // \ -> \\
                // , -> \,
                // In String#replaceAll(), "\\\\" means a single backslash.
                builder.append("=");
                builder.append(entry.getValue().toString()
                        .replaceAll("\\\\", "\\\\\\\\")
                        .replaceAll(",", "\\\\,"));
                if (i < size -1) {
                    builder.append(",");
                }
                i++;
            }

            Set<String> set = paramMap_TYPE;
            size = paramMap_TYPE.size();
            if (i > 0 && size > 0) {
                builder.append(",");
            }
            i = 0;
            for (String type : set) {
                builder.append("TYPE=");
                builder.append(type
                        .replaceAll("\\\\", "\\\\\\\\")
                        .replaceAll(",", "\\\\,"));
                if (i < size - 1) {
                    builder.append(",");
                }
                i++;
            }
            builder.append("],");
        }

        size = propValue_vector.size();
        if (size > 0) {
            builder.append("propValue:[");
            List<String> list = propValue_vector;
            for (int i = 0; i < size; i++) {
                builder.append(list.get(i)
                        .replaceAll("\\\\", "\\\\\\\\")
                        .replaceAll(",", "\\\\,"));
                if (i < size -1) {
                    builder.append(",");
                }
            }
            builder.append("],");
        }

        return builder.toString();
    }

    public static PropertyNode decode(String encodedString) {
        PropertyNode propertyNode = new PropertyNode();
        String trimed = encodedString.trim();
        if (trimed.length() == 0) {
            return propertyNode;
        }
        String[] elems = trimed.split("],");
        
        for (String elem : elems) {
            int index = elem.indexOf('[');
            String name = elem.substring(0, index - 1);
            Pattern pattern = Pattern.compile("(?<!\\\\),");
            String[] values = pattern.split(elem.substring(index + 1), -1);
            if (name.equals("propName")) {
                propertyNode.propName = values[0];
            } else if (name.equals("propGroupSet")) {
                for (String value : values) {
                    propertyNode.propGroupSet.add(value);
                }
            } else if (name.equals("paramMap")) {
                ContentValues paramMap = propertyNode.paramMap;
                Set<String> paramMap_TYPE = propertyNode.paramMap_TYPE;
                for (String value : values) {
                    String[] tmp = value.split("=", 2);
                    String mapKey = tmp[0];
                    // \, -> ,
                    // \\ -> \
                    // In String#replaceAll(), "\\\\" means a single backslash.
                    String mapValue =
                        tmp[1].replaceAll("\\\\,", ",").replaceAll("\\\\\\\\", "\\\\");
                    if (mapKey.equalsIgnoreCase("TYPE")) {
                        paramMap_TYPE.add(mapValue);
                    } else {
                        paramMap.put(mapKey, mapValue);
                    }
                }
            } else if (name.equals("propValue")) {
                StringBuilder builder = new StringBuilder();
                List<String> list = propertyNode.propValue_vector;
                int length = values.length;
                for (int i = 0; i < length; i++) {
                    String normValue = values[i]
                                              .replaceAll("\\\\,", ",")
                                              .replaceAll("\\\\\\\\", "\\\\");
                    list.add(normValue);
                    builder.append(normValue);
                    if (i < length - 1) {
                        builder.append(";");
                    }
                }
                propertyNode.propValue = builder.toString();
            }
        }
        
        // At this time, QUOTED-PRINTABLE is already decoded to Java String.
        // We just need to decode BASE64 String to binary.
        String encoding = propertyNode.paramMap.getAsString("ENCODING");
        if (encoding != null &&
                (encoding.equalsIgnoreCase("BASE64") ||
                        encoding.equalsIgnoreCase("B"))) {
            propertyNode.propValue_bytes =
                Base64.decodeBase64(propertyNode.propValue_vector.get(0).getBytes());
        }
        
        return propertyNode;
    }
}
}
+100 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.syncml.pim;

import java.util.Collection;
import java.util.List;

public class VBuilderCollection implements VBuilder {

    private final Collection<VBuilder> mVBuilderCollection;
    
    public VBuilderCollection(Collection<VBuilder> vBuilderCollection) {
        mVBuilderCollection = vBuilderCollection; 
    }
    
    public Collection<VBuilder> getVBuilderCollection() {
        return mVBuilderCollection;
    }
    
    public void start() {
        for (VBuilder builder : mVBuilderCollection) {
            builder.start();
        }
    }
    
    public void end() {
        for (VBuilder builder : mVBuilderCollection) {
            builder.end();
        }
    }

    public void startRecord(String type) {
        for (VBuilder builder : mVBuilderCollection) {
            builder.startRecord(type);
        }
    }
    
    public void endRecord() {
        for (VBuilder builder : mVBuilderCollection) {
            builder.endRecord();
        }
    }

    public void startProperty() {
        for (VBuilder builder : mVBuilderCollection) {
            builder.startProperty();
        }
    }

    
    public void endProperty() {
        for (VBuilder builder : mVBuilderCollection) {
            builder.endProperty();
        }
    }

    public void propertyGroup(String group) {
        for (VBuilder builder : mVBuilderCollection) {
            builder.propertyGroup(group);
        }
    }

    public void propertyName(String name) {
        for (VBuilder builder : mVBuilderCollection) {
            builder.propertyName(name);
        }
    }

    public void propertyParamType(String type) {
        for (VBuilder builder : mVBuilderCollection) {
            builder.propertyParamType(type);
        }
    }

    public void propertyParamValue(String value) {
        for (VBuilder builder : mVBuilderCollection) {
            builder.propertyParamValue(value);
        }
    }

    public void propertyValues(List<String> values) {
        for (VBuilder builder : mVBuilderCollection) {
            builder.propertyValues(values);
        }
    }
}
+172 −121

File changed.

Preview size limit exceeded, changes collapsed.

Loading