summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDanesh M <daneshm90@gmail.com>2014-12-16 17:20:05 -0800
committerSteve Kondik <steve@cyngn.com>2015-10-18 13:52:41 -0700
commit95ebfec6b5b543b130a7c19cefe1b1b0da1e466b (patch)
tree1ef7d87a0c4fa12235de0a9601bf4d6a3192cc27 /src
parent4c1cb1bec37d25fdbaa98039cf56fcd125e5eba0 (diff)
downloadandroid_packages_apps_Calendar-95ebfec6b5b543b130a7c19cefe1b1b0da1e466b.tar.gz
android_packages_apps_Calendar-95ebfec6b5b543b130a7c19cefe1b1b0da1e466b.tar.bz2
android_packages_apps_Calendar-95ebfec6b5b543b130a7c19cefe1b1b0da1e466b.zip
Calendar : Add ability to import/export from sdcard
Change-Id: Ia2ae56b50bff764786cdd37b760eb6b94a63743f
Diffstat (limited to 'src')
-rw-r--r--src/com/android/calendar/AllInOneActivity.java5
-rw-r--r--src/com/android/calendar/EventInfoFragment.java99
-rw-r--r--src/com/android/calendar/ImportActivity.java186
-rw-r--r--src/com/android/calendar/icalendar/Attendee.java10
-rw-r--r--src/com/android/calendar/icalendar/IcalendarUtils.java124
-rw-r--r--src/com/android/calendar/icalendar/Organizer.java8
-rw-r--r--src/com/android/calendar/icalendar/VCalendar.java27
-rw-r--r--src/com/android/calendar/icalendar/VEvent.java44
8 files changed, 462 insertions, 41 deletions
diff --git a/src/com/android/calendar/AllInOneActivity.java b/src/com/android/calendar/AllInOneActivity.java
index d9e1a9ca..b43a1262 100644
--- a/src/com/android/calendar/AllInOneActivity.java
+++ b/src/com/android/calendar/AllInOneActivity.java
@@ -772,6 +772,9 @@ public class AllInOneActivity extends AbstractCalendarActivity implements EventH
getMenuInflater().inflate(extensionMenuRes, menu);
}
+ MenuItem item = menu.findItem(R.id.action_import);
+ item.setVisible(ImportActivity.hasThingsToImport(this));
+
mSearchMenu = menu.findItem(R.id.action_search);
mSearchView = (SearchView) mSearchMenu.getActionView();
if (mSearchView != null) {
@@ -885,6 +888,8 @@ public class AllInOneActivity extends AbstractCalendarActivity implements EventH
GoToDialogFragment goToFrg = GoToDialogFragment.newInstance(timeZone);
goToFrg.show(getFragmentManager(), "goto");
return true;
+ } else if (itemId == R.id.action_import) {
+ ImportActivity.pickImportFile(this);
} else {
return mExtensions.handleItemSelected(item, this);
}
diff --git a/src/com/android/calendar/EventInfoFragment.java b/src/com/android/calendar/EventInfoFragment.java
index 90f73b02..4374226e 100644
--- a/src/com/android/calendar/EventInfoFragment.java
+++ b/src/com/android/calendar/EventInfoFragment.java
@@ -48,6 +48,7 @@ import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
+import android.os.Environment;
import android.provider.CalendarContract;
import android.provider.CalendarContract.Attendees;
import android.provider.CalendarContract.Calendars;
@@ -185,6 +186,14 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
| TOKEN_QUERY_ATTENDEES | TOKEN_QUERY_CALENDARS | TOKEN_QUERY_EVENT
| TOKEN_QUERY_REMINDERS | TOKEN_QUERY_VISIBLE_CALENDARS | TOKEN_QUERY_COLORS;
+ public static final File EXPORT_SDCARD_DIRECTORY = new File(
+ Environment.getExternalStorageDirectory(), "CalendarEvents");
+
+ private enum ShareType {
+ SDCARD,
+ INTENT
+ }
+
private int mCurrentQuery = 0;
private static final String[] EVENT_PROJECTION = new String[] {
@@ -1258,7 +1267,9 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
} else if (itemId == R.id.info_action_change_color) {
showEventColorPickerDialog();
} else if (itemId == R.id.info_action_share_event) {
- shareEvent();
+ shareEvent(ShareType.INTENT);
+ } else if (itemId == R.id.info_action_export) {
+ shareEvent(ShareType.SDCARD);
}
return super.onOptionsItemSelected(item);
}
@@ -1267,7 +1278,7 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
* Generates an .ics formatted file with the event info and launches intent chooser to
* share said file
*/
- private void shareEvent() {
+ private void shareEvent(ShareType type) {
// Create the respective ICalendar objects from the event info
VCalendar calendar = new VCalendar();
calendar.addProperty(VCalendar.VERSION, "2.0");
@@ -1330,37 +1341,62 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
// prefix length constraint is imposed by File#createTempFile
filePrefix = "invite";
}
- File inviteFile = File.createTempFile(filePrefix, ".ics",
- mActivity.getExternalCacheDir());
+
+ filePrefix = filePrefix.replaceAll("\\W+", " ");
+
+ if (!filePrefix.endsWith(" ")) {
+ filePrefix += " ";
+ }
+
+ File dir;
+ if (type == ShareType.SDCARD) {
+ dir = EXPORT_SDCARD_DIRECTORY;
+ if (!dir.exists()) {
+ dir.mkdir();
+ }
+ } else {
+ dir = mActivity.getExternalCacheDir();
+ }
+
+ File inviteFile = IcalendarUtils.createTempFile(filePrefix, ".ics",
+ dir);
+
if (IcalendarUtils.writeCalendarToFile(calendar, inviteFile)) {
- inviteFile.setReadable(true,false); // set world-readable
- Intent shareIntent = new Intent();
- shareIntent.setAction(Intent.ACTION_SEND);
- shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(inviteFile));
- // the ics file is sent as an extra, the receiving application decides whether to
- // parse the file to extract calendar events or treat it as a regular file
- shareIntent.setType("application/octet-stream");
-
- Intent chooserIntent = Intent.createChooser(shareIntent,
- getResources().getString(R.string.cal_share_intent_title));
-
- // The MMS app only responds to "text/x-vcalendar" so we create a chooser intent
- // that includes the targeted mms intent + any that respond to the above general
- // purpose "application/octet-stream" intent.
- File vcsInviteFile = File.createTempFile(filePrefix, ".vcs",
- mActivity.getExternalCacheDir());
- // for now , we are duplicating ics file and using that as the vcs file
- // TODO: revisit above
- if (IcalendarUtils.copyFile(inviteFile, vcsInviteFile)) {
- Intent mmsShareIntent = new Intent();
- mmsShareIntent.setAction(Intent.ACTION_SEND);
- mmsShareIntent.setPackage("com.android.mms");
- mmsShareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(vcsInviteFile));
- mmsShareIntent.setType("text/x-vcalendar");
- chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS,
- new Intent[]{mmsShareIntent});
+ if (type == ShareType.INTENT) {
+ inviteFile.setReadable(true, false); // set world-readable
+ Intent shareIntent = new Intent();
+ shareIntent.setAction(Intent.ACTION_SEND);
+ shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(inviteFile));
+ // the ics file is sent as an extra, the receiving application decides whether
+ // to parse the file to extract calendar events or treat it as a regular file
+ shareIntent.setType("application/octet-stream");
+
+ Intent chooserIntent = Intent.createChooser(shareIntent,
+ getResources().getString(R.string.cal_share_intent_title));
+
+ // The MMS app only responds to "text/x-vcalendar" so we create a chooser intent
+ // that includes the targeted mms intent + any that respond to the above general
+ // purpose "application/octet-stream" intent.
+ File vcsInviteFile = File.createTempFile(filePrefix, ".vcs",
+ mActivity.getExternalCacheDir());
+
+ // for now , we are duplicating ics file and using that as the vcs file
+ // TODO: revisit above
+ if (IcalendarUtils.copyFile(inviteFile, vcsInviteFile)) {
+ Intent mmsShareIntent = new Intent();
+ mmsShareIntent.setAction(Intent.ACTION_SEND);
+ mmsShareIntent.setPackage("com.android.mms");
+ mmsShareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(vcsInviteFile));
+ mmsShareIntent.setType("text/x-vcalendar");
+ chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS,
+ new Intent[]{mmsShareIntent});
+ }
+ startActivity(chooserIntent);
+ } else {
+ String msg = getString(R.string.cal_export_succ_msg);
+ Toast.makeText(mActivity, String.format(msg, inviteFile),
+ Toast.LENGTH_SHORT).show();
}
- startActivity(chooserIntent);
isShareSuccessful = true;
} else {
@@ -1368,6 +1404,7 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
isShareSuccessful = false;
}
} catch (IOException e) {
+ e.printStackTrace();
isShareSuccessful = false;
}
diff --git a/src/com/android/calendar/ImportActivity.java b/src/com/android/calendar/ImportActivity.java
new file mode 100644
index 00000000..0a4a89a1
--- /dev/null
+++ b/src/com/android/calendar/ImportActivity.java
@@ -0,0 +1,186 @@
+package com.android.calendar;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.ActivityNotFoundException;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.provider.CalendarContract;
+import android.text.TextUtils;
+import android.widget.Toast;
+import com.android.calendar.icalendar.Attendee;
+import com.android.calendar.icalendar.IcalendarUtils;
+import com.android.calendar.icalendar.VCalendar;
+import com.android.calendar.icalendar.VEvent;
+
+import java.io.File;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.LinkedList;
+import java.util.TimeZone;
+
+public class ImportActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (!isValidIntent()) {
+ Toast.makeText(this, R.string.cal_nothing_to_import, Toast.LENGTH_SHORT).show();
+ finish();
+ } else {
+ parseCalFile();
+ }
+ }
+
+ private long getLocalTimeFromString(String iCalDate) {
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'");
+ format.setTimeZone(TimeZone.getTimeZone("UTC"));
+
+ try {
+ format.parse(iCalDate);
+ format.setTimeZone(TimeZone.getDefault());
+ return format.getCalendar().getTimeInMillis();
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+
+ return System.currentTimeMillis();
+ }
+
+ private void showErrorToast() {
+ Toast.makeText(this, R.string.cal_import_error_msg, Toast.LENGTH_SHORT).show();
+ finish();
+ }
+
+ private void parseCalFile() {
+ Uri uri = getIntent().getData();
+ VCalendar calendar = IcalendarUtils.readCalendarFromFile(this, uri);
+
+ if (calendar == null) {
+ showErrorToast();
+ return;
+ }
+
+ Intent calIntent = new Intent(Intent.ACTION_INSERT);
+ calIntent.setType("vnd.android.cursor.item/event");
+
+ LinkedList<VEvent> events = calendar.getAllEvents();
+ if (events == null) {
+ showErrorToast();
+ return;
+ }
+
+ VEvent firstEvent = calendar.getAllEvents().getFirst();
+ calIntent.putExtra(CalendarContract.Events.TITLE,
+ IcalendarUtils.uncleanseString(firstEvent.getProperty(VEvent.SUMMARY)));
+ calIntent.putExtra(CalendarContract.Events.EVENT_LOCATION,
+ IcalendarUtils.uncleanseString(firstEvent.getProperty(VEvent.LOCATION)));
+ calIntent.putExtra(CalendarContract.Events.DESCRIPTION,
+ IcalendarUtils.uncleanseString(firstEvent.getProperty(VEvent.DESCRIPTION)));
+ calIntent.putExtra(CalendarContract.Events.ORGANIZER,
+ IcalendarUtils.uncleanseString(firstEvent.getProperty(VEvent.ORGANIZER)));
+
+ if (firstEvent.mAttendees.size() > 0) {
+ StringBuilder builder = new StringBuilder();
+ for (Attendee attendee : firstEvent.mAttendees) {
+ builder.append(attendee.mEmail);
+ builder.append(",");
+ }
+ calIntent.putExtra(Intent.EXTRA_EMAIL, builder.toString());
+ }
+
+ String dtStart = firstEvent.getProperty(VEvent.DTSTART);
+ if (!TextUtils.isEmpty(dtStart)) {
+ calIntent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME,
+ getLocalTimeFromString(dtStart));
+ }
+
+ String dtEnd = firstEvent.getProperty(VEvent.DTEND);
+ if (!TextUtils.isEmpty(dtEnd)) {
+ calIntent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME,
+ getLocalTimeFromString(dtEnd));
+ }
+
+ try {
+ startActivity(calIntent);
+ } catch (ActivityNotFoundException e) {
+ // Oh well...
+ } finally {
+ finish();
+ }
+ }
+
+ private boolean isValidIntent() {
+ Intent intent = getIntent();
+ if (intent == null) {
+ return false;
+ }
+ Uri fileUri = intent.getData();
+ if (fileUri == null) {
+ return false;
+ }
+ String scheme = fileUri.getScheme();
+ return ContentResolver.SCHEME_CONTENT.equals(scheme)
+ || ContentResolver.SCHEME_FILE.equals(scheme);
+ }
+
+ private static class ListFilesTask extends AsyncTask<Void, Void, String[]> {
+
+ private final Activity mActivity;
+
+ public ListFilesTask(Activity activity) {
+ mActivity = activity;
+ }
+
+ @Override
+ protected String[] doInBackground(Void... params) {
+ if (!hasThingsToImport(mActivity)) {
+ return null;
+ }
+ File folder = EventInfoFragment.EXPORT_SDCARD_DIRECTORY;
+ String[] result = null;
+ if (folder.exists()) {
+ result = folder.list();
+ }
+ return result;
+ }
+
+ @Override
+ protected void onPostExecute(final String[] files) {
+ if (files == null || files.length == 0) {
+ Toast.makeText(mActivity, R.string.cal_nothing_to_import,
+ Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
+ builder.setTitle(R.string.cal_pick_ics)
+ .setItems(files, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ Intent i = new Intent(mActivity, ImportActivity.class);
+ File f = new File(EventInfoFragment.EXPORT_SDCARD_DIRECTORY,
+ files[which]);
+ i.setData(Uri.fromFile(f));
+ mActivity.startActivity(i);
+ }
+ });
+ builder.show();
+ }
+
+ }
+
+ public static void pickImportFile(Activity activity) {
+ new ListFilesTask(activity).execute();
+ }
+
+ public static boolean hasThingsToImport(Context context) {
+ File folder = EventInfoFragment.EXPORT_SDCARD_DIRECTORY;
+ return folder.exists() && folder.list().length > 0;
+ }
+
+}
diff --git a/src/com/android/calendar/icalendar/Attendee.java b/src/com/android/calendar/icalendar/Attendee.java
index fc8c78bb..c3c2ba84 100644
--- a/src/com/android/calendar/icalendar/Attendee.java
+++ b/src/com/android/calendar/icalendar/Attendee.java
@@ -5,6 +5,7 @@
package com.android.calendar.icalendar;
import java.util.HashMap;
+import java.util.ListIterator;
/**
* Models the Attendee component of a calendar event
@@ -74,4 +75,13 @@ public class Attendee {
return output.toString();
}
+ public void populateFromEntries(ListIterator<String> iter) {
+ String line = iter.next();
+ if (line.contains("ATTENDEE")) {
+ String entry = VEvent.parseTillNextAttribute(iter, line);
+ String[] entries = entry.split("X-NUM-GUESTS=0:mailto:");
+ mEmail = entries[1];
+ }
+ }
+
}
diff --git a/src/com/android/calendar/icalendar/IcalendarUtils.java b/src/com/android/calendar/icalendar/IcalendarUtils.java
index e179926b..efbb4583 100644
--- a/src/com/android/calendar/icalendar/IcalendarUtils.java
+++ b/src/com/android/calendar/icalendar/IcalendarUtils.java
@@ -4,20 +4,17 @@
package com.android.calendar.icalendar;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.net.Uri;
import android.provider.CalendarContract;
-import android.util.Log;
import com.android.calendar.CalendarEventModel;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
+import java.io.*;
import java.text.SimpleDateFormat;
+import java.util.ArrayList;
import java.util.Calendar;
-import java.util.Date;
+import java.util.Random;
import java.util.TimeZone;
/**
@@ -25,7 +22,21 @@ import java.util.TimeZone;
*/
public class IcalendarUtils {
- private static int sPermittedLineLength = 75; // Line length mandated by iCalendar format
+ public static int sPermittedLineLength = 75; // Line length mandated by iCalendar format
+ private static final Random tempFileRandom = new Random();
+
+ public static String uncleanseString(CharSequence sequence) {
+ if (sequence == null) return null;
+ String input = sequence.toString();
+
+ // reintroduce new lines with the literal '\n'
+ input = input.replaceAll("\\\\n", "\n");
+ // reintroduce semicolons and commas
+ input = input.replaceAll("\\\\;", ";");
+ input = input.replaceAll("\\\\\\,", ",");
+
+ return input;
+ }
/**
* ensure the string conforms to the iCalendar encoding requirements
@@ -47,6 +58,99 @@ public class IcalendarUtils {
}
/**
+ * Creates an empty temporary file in the given directory using the given
+ * prefix and suffix as part of the file name. If {@code suffix} is null, {@code .tmp} is used.
+ *
+ * <p>Note that this method does <i>not</i> call {@link #deleteOnExit}, but see the
+ * documentation for that method before you call it manually.
+ *
+ * @param prefix
+ * the prefix to the temp file name.
+ * @param suffix
+ * the suffix to the temp file name.
+ * @param directory
+ * the location to which the temp file is to be written, or
+ * {@code null} for the default location for temporary files,
+ * which is taken from the "java.io.tmpdir" system property. It
+ * may be necessary to set this property to an existing, writable
+ * directory for this method to work properly.
+ * @return the temporary file.
+ * @throws IllegalArgumentException
+ * if the length of {@code prefix} is less than 3.
+ * @throws IOException
+ * if an error occurs when writing the file.
+ */
+ public static File createTempFile(String prefix, String suffix, File directory)
+ throws IOException {
+ // Force a prefix null check first
+ if (prefix.length() < 3) {
+ throw new IllegalArgumentException("prefix must be at least 3 characters");
+ }
+ if (suffix == null) {
+ suffix = ".tmp";
+ }
+ File tmpDirFile = directory;
+ if (tmpDirFile == null) {
+ String tmpDir = System.getProperty("java.io.tmpdir", ".");
+ tmpDirFile = new File(tmpDir);
+ }
+ File result;
+ do {
+ result = new File(tmpDirFile,
+ prefix + tempFileRandom.nextInt(Integer.MAX_VALUE) + suffix);
+ } while (!result.createNewFile());
+ return result;
+ }
+
+ public static VCalendar readCalendarFromFile(Context context, Uri uri) {
+ ArrayList<String> contents = getStringArrayFromFile(context, uri);
+ if (contents == null || contents.isEmpty()) {
+ return null;
+ }
+ VCalendar calendar = new VCalendar();
+ calendar.populateFromString(contents);
+ return calendar;
+ }
+
+ public static ArrayList<String> getStringArrayFromFile(Context context, Uri uri) {
+ String scheme = uri.getScheme();
+ InputStream inputStream = null;
+ if(ContentResolver.SCHEME_CONTENT.equals(scheme)) {
+ try {
+ inputStream = context.getContentResolver().openInputStream(uri);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ } else if (ContentResolver.SCHEME_FILE.equals(scheme)) {
+ File f = new File(uri.getPath());
+ try {
+ inputStream = new FileInputStream(f);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+
+ if (inputStream == null) {
+ return null;
+ }
+
+ ArrayList<String> result = new ArrayList<String>();
+
+ try {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
+ String line;
+ while ((line = reader.readLine()) != null) {
+ result.add(line);
+ }
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return result;
+ }
+
+ /**
* Stringify VCalendar object and write to file
* @param calendar
* @param file
diff --git a/src/com/android/calendar/icalendar/Organizer.java b/src/com/android/calendar/icalendar/Organizer.java
index 2e039849..9f9780d5 100644
--- a/src/com/android/calendar/icalendar/Organizer.java
+++ b/src/com/android/calendar/icalendar/Organizer.java
@@ -39,4 +39,12 @@ public class Organizer {
return output.toString();
}
+ public static Organizer populateFromICalString(String iCalFormattedString) {
+ // TODO add santiy checks
+ String[] organizer = iCalFormattedString.split(";");
+ String[] entries = organizer[1].split(":");
+ String name = entries[0].replace("CN=", "");
+ String email = entries[1].replace("mailto=", "");
+ return new Organizer(name, email);
+ }
}
diff --git a/src/com/android/calendar/icalendar/VCalendar.java b/src/com/android/calendar/icalendar/VCalendar.java
index 00c7b81b..9f422e6f 100644
--- a/src/com/android/calendar/icalendar/VCalendar.java
+++ b/src/com/android/calendar/icalendar/VCalendar.java
@@ -4,8 +4,12 @@
package com.android.calendar.icalendar;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
/**
* Models the Calendar/VCalendar component of the iCalendar format
@@ -102,6 +106,29 @@ public class VCalendar {
return output.toString();
}
+ public void populateFromString(ArrayList<String> input) {
+ ListIterator<String> iter = input.listIterator();
+
+ while (iter.hasNext()) {
+ String line = iter.next();
+ if (line.contains("BEGIN:VEVENT")) {
+ // Go one previous, so VEvent, parses current line
+ iter.previous();
+
+ // Offload to vevent for parsing
+ VEvent event = new VEvent();
+ event.populateFromEntries(iter);
+ mEvents.add(event);
+ } else if (line.contains("END:VCALENDAR")) {
+ break;
+ }
+ }
+ }
+
+ public String getProperty(String key) {
+ return mProperties.get(key);
+ }
+
/**
* TODO: Aggressive validation of VCalendar and all of its components to ensure they conform
* to the ical specification
diff --git a/src/com/android/calendar/icalendar/VEvent.java b/src/com/android/calendar/icalendar/VEvent.java
index 1aff0bd4..672aa18b 100644
--- a/src/com/android/calendar/icalendar/VEvent.java
+++ b/src/com/android/calendar/icalendar/VEvent.java
@@ -6,6 +6,7 @@ package com.android.calendar.icalendar;
import java.util.HashMap;
import java.util.LinkedList;
+import java.util.ListIterator;
import java.util.UUID;
/**
@@ -173,4 +174,47 @@ public class VEvent {
return sb.toString();
}
+ public void populateFromEntries(ListIterator<String> iter) {
+ while (iter.hasNext()) {
+ String line = iter.next();
+ if (line.contains("BEGIN:VEVENT")) {
+ // Continue
+ } else if (line.startsWith("END:EVENT")) {
+ break;
+ } else if (line.startsWith("ORGANIZER")) {
+ String entry = parseTillNextAttribute(iter, line);
+ mOrganizer = Organizer.populateFromICalString(entry);
+ } else if (line.startsWith("ATTENDEE")) {
+ // Go one previous, so VEvent, parses current line
+ iter.previous();
+
+ // Offload to Attendee for parsing
+ Attendee attendee = new Attendee();
+ attendee.populateFromEntries(iter);
+ mAttendees.add(attendee);
+ } else if (line.contains(":")) {
+ String entry = parseTillNextAttribute(iter, line);
+ int indexOfFirstColon = entry.indexOf(":");
+ String key = entry.substring(0, indexOfFirstColon);
+ String value = entry.substring(indexOfFirstColon + 1);
+ mProperties.put(key, value);
+ }
+ }
+ }
+
+ public static String parseTillNextAttribute(ListIterator<String> iter, String currentLine) {
+ StringBuilder parse = new StringBuilder();
+ parse.append(currentLine);
+ while (iter.hasNext()) {
+ String line = iter.next();
+ if (line.startsWith(" ")) {
+ parse.append(line.replaceFirst(" ", ""));
+ } else {
+ iter.previous();
+ break;
+ }
+ }
+ return parse.toString();
+ }
+
}