Skip to content

Commit

Permalink
Allow URIs in place of the URI field. #411 (#580)
Browse files Browse the repository at this point in the history
  • Loading branch information
Gabor Keszthelyi authored and dmfs committed Dec 20, 2017
1 parent 866af2b commit 62e6af8
Show file tree
Hide file tree
Showing 8 changed files with 308 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ public interface TaskColumns
String DESCRIPTION = "description";

/**
* An URL for this task. Must be a valid URL if not <code>null</code>-
* The URL iCalendar field for this task. Must be a valid URI if not <code>null</code>-
* <p>
* Value: String
* </p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
import org.dmfs.tasks.model.adapters.StringFieldAdapter;
import org.dmfs.tasks.model.adapters.TimeFieldAdapter;
import org.dmfs.tasks.model.adapters.TimezoneFieldAdapter;
import org.dmfs.tasks.model.adapters.UrlFieldAdapter;
import org.dmfs.tasks.model.adapters.UriFieldAdapter;
import org.dmfs.tasks.model.constraints.AdjustPercentComplete;
import org.dmfs.tasks.model.constraints.After;
import org.dmfs.tasks.model.constraints.BeforeOrShiftTime;
Expand Down Expand Up @@ -140,7 +140,7 @@ public final class TaskFieldAdapters
/**
* Adapter for the URL of a task.
*/
public final static UrlFieldAdapter URL = new UrlFieldAdapter(TaskContract.Tasks.URL);
public final static UriFieldAdapter URL = new UriFieldAdapter(TaskContract.Tasks.URL);

/**
* Adapter for the Color of the task.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,53 +18,54 @@

import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;

import org.dmfs.tasks.model.ContentSet;
import org.dmfs.tasks.model.OnContentChangeListener;
import org.dmfs.tasks.utils.ValidatingUri;

import java.net.MalformedURLException;
import java.net.URL;
import java.net.URISyntaxException;


/**
* Knows how to load and store {@link URL} values in a {@link ContentSet}.
* Knows how to load and store {@link Uri} values in a {@link ContentSet}.
*
* @author Marten Gajda <marten@dmfs.org>
*/
public final class UrlFieldAdapter extends FieldAdapter<URL>
public final class UriFieldAdapter extends FieldAdapter<Uri>
{

private final String mFieldName;

private final URL mDefaultValue;
private final Uri mDefaultValue;


/**
* Constructor for a new urlFieldAdapter without default value.
* Constructor for a new {@link UriFieldAdapter} without default value.
*
* @param urlField
* The field name that holds the URL.
* @param uriField
* The field name that holds the URI.
*/
public UrlFieldAdapter(String urlField)
public UriFieldAdapter(String uriField)
{
if (urlField == null)
if (uriField == null)
{
throw new IllegalArgumentException("urlField must not be null");
throw new IllegalArgumentException("uriField must not be null");
}
mFieldName = urlField;
mFieldName = uriField;
mDefaultValue = null;
}


/**
* Constructor for a new UrlFieldAdapter with default value.
* Constructor for a new {@link UriFieldAdapter} with default value.
*
* @param fieldName
* @param urlField
* The name of the field to use when loading or storing the value.
* @param defaultValue
* The defaultValue.
*/
public UrlFieldAdapter(String urlField, URL defaultValue)
public UriFieldAdapter(String urlField, Uri defaultValue)
{
if (urlField == null)
{
Expand All @@ -76,21 +77,21 @@ public UrlFieldAdapter(String urlField, URL defaultValue)


@Override
public URL get(ContentSet values)
public Uri get(ContentSet values)
{
try
{
return new URL(values.getAsString(mFieldName));
return new ValidatingUri(values.getAsString(mFieldName)).value();
}
catch (MalformedURLException e)
catch (URISyntaxException e)
{
return null;
}
}


@Override
public URL get(Cursor cursor)
public Uri get(Cursor cursor)
{
int columnIdx = cursor.getColumnIndex(mFieldName);
if (columnIdx < 0)
Expand All @@ -99,24 +100,24 @@ public URL get(Cursor cursor)
}
try
{
return new URL(cursor.getString(columnIdx));
return new ValidatingUri(cursor.getString(columnIdx)).value();
}
catch (MalformedURLException e)
catch (URISyntaxException e)
{
return null;
}
}


@Override
public URL getDefault(ContentSet values)
public Uri getDefault(ContentSet values)
{
return mDefaultValue;
}


@Override
public void set(ContentSet values, URL value)
public void set(ContentSet values, Uri value)
{
if (value == null)
{
Expand All @@ -130,7 +131,7 @@ public void set(ContentSet values, URL value)


@Override
public void set(ContentValues values, URL value)
public void set(ContentValues values, Uri value)
{
if (value == null)
{
Expand Down
37 changes: 37 additions & 0 deletions opentasks/src/main/java/org/dmfs/tasks/utils/Fragile.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright 2017 dmfs GmbH
*
* 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 org.dmfs.tasks.utils;

import org.dmfs.jems.single.Single;

import java.util.Iterator;


/**
* A Fragile is similar to a {@link Single} but it may throw an {@link Exception} during retrieval of the value.
* <p>
* It's primary use case is to allow deferring checked Exceptions if they can't be thrown right away. A common example is Iterating elements, {@link
* Iterator#next()} doesn't allow checked Exceptions to be thrown. In this case a {@link Fragile} can be returned to defer any exception to evaluation time.
*
* @author Marten Gajda
* @deprecated use it from jems when available
*/
@Deprecated
public interface Fragile<T, E extends Throwable>
{
T value() throws E;
}
57 changes: 57 additions & 0 deletions opentasks/src/main/java/org/dmfs/tasks/utils/ValidatingUri.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright 2017 dmfs GmbH
*
* 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 org.dmfs.tasks.utils;

import android.net.Uri;
import android.support.annotation.Nullable;

import java.net.URI;
import java.net.URISyntaxException;


/**
* A {@link Fragile} to create a valid {@link Uri} from a {@link Nullable} {@link CharSequence}.
* <p>
* Throws {@link URISyntaxException} for invalid or <code>null</code> or empty input.
*
* @author Gabor Keszthelyi
*/
public final class ValidatingUri implements Fragile<Uri, URISyntaxException>
{
private final CharSequence mUriCandidate;


public ValidatingUri(@Nullable CharSequence uriCandidate)
{
mUriCandidate = uriCandidate;
}


@Override
public Uri value() throws URISyntaxException
{
if (mUriCandidate == null)
{
throw new URISyntaxException("null", "Uri input cannot be null");
}
if (mUriCandidate.length() == 0)
{
throw new URISyntaxException("", "Uri input cannot be empty");
}
return Uri.parse(new URI(mUriCandidate.toString()).toString());
}
}
22 changes: 11 additions & 11 deletions opentasks/src/main/java/org/dmfs/tasks/widget/UrlFieldEditor.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package org.dmfs.tasks.widget;

import android.content.Context;
import android.net.Uri;
import android.os.Build.VERSION;
import android.text.Editable;
import android.text.InputType;
Expand All @@ -29,11 +30,11 @@
import org.dmfs.tasks.model.ContentSet;
import org.dmfs.tasks.model.FieldDescriptor;
import org.dmfs.tasks.model.adapters.FieldAdapter;
import org.dmfs.tasks.model.adapters.UrlFieldAdapter;
import org.dmfs.tasks.model.adapters.UriFieldAdapter;
import org.dmfs.tasks.model.layout.LayoutOptions;
import org.dmfs.tasks.utils.ValidatingUri;

import java.net.MalformedURLException;
import java.net.URL;
import java.net.URISyntaxException;


/**
Expand All @@ -47,7 +48,7 @@ public final class UrlFieldEditor extends AbstractFieldEditor implements TextWat
/**
* The {@link FieldAdapter} of the field for this view.
*/
private UrlFieldAdapter mAdapter;
private UriFieldAdapter mAdapter;

/**
* The {@link EditText} to edit the URL.
Expand Down Expand Up @@ -100,15 +101,15 @@ public void onContentChanged(ContentSet contentSet)
{
if (mValues != null)
{
URL newUrl = mAdapter.get(mValues);
if (newUrl == null)
Uri newUri = mAdapter.get(mValues);
if (newUri == null)
{
mText.setText(null);
}
else
{
String oldValue = mText.getText().toString();
String newValue = newUrl.toString();
String newValue = newUri.toString();
if (!TextUtils.equals(oldValue, newValue)) // don't trigger unnecessary updates
{
mText.setText(newValue);
Expand All @@ -122,7 +123,7 @@ public void onContentChanged(ContentSet contentSet)
public void setFieldDescription(FieldDescriptor descriptor, LayoutOptions layoutOptions)
{
super.setFieldDescription(descriptor, layoutOptions);
mAdapter = (UrlFieldAdapter) descriptor.getFieldAdapter();
mAdapter = (UriFieldAdapter) descriptor.getFieldAdapter();
mText.setHint(descriptor.getHint());
}

Expand All @@ -137,18 +138,17 @@ public void afterTextChanged(Editable s)
String text = mText.getText().toString();
if (!TextUtils.isEmpty(text))
{
mAdapter.set(mValues, new URL(text));
mAdapter.set(mValues, new ValidatingUri(text).value());
}
else
{
mAdapter.set(mValues, null);
}
mText.setError(null);
}
catch (MalformedURLException e)
catch (URISyntaxException e)
{
mText.setError(getContext().getString(R.string.activity_edit_task_error_invalid_url));
e.printStackTrace();
}
}
}
Expand Down
Loading

0 comments on commit 62e6af8

Please sign in to comment.