├── settings.gradle
├── .gitignore
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── samples
├── src
│ └── main
│ │ ├── assets
│ │ ├── Ubuntu-M.ttf
│ │ └── ubuntu-font-license-1.0.txt
│ │ ├── res
│ │ ├── drawable-xhdpi
│ │ │ └── ic_launcher.png
│ │ ├── values
│ │ │ ├── attrs.xml
│ │ │ └── strings.xml
│ │ └── layout
│ │ │ ├── main.xml
│ │ │ └── main_frag.xml
│ │ ├── java
│ │ └── com
│ │ │ └── madisp
│ │ │ └── pretty
│ │ │ └── samples
│ │ │ ├── SampleActivity.java
│ │ │ ├── SampleFragment.java
│ │ │ └── FontDecor.java
│ │ └── AndroidManifest.xml
└── build.gradle
├── tests
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── madisp
│ │ │ │ └── pretty
│ │ │ │ ├── FragInLayoutActivity.java
│ │ │ │ ├── TestFragment.java
│ │ │ │ └── CreatesFragActivity.java
│ │ ├── res
│ │ │ ├── values
│ │ │ │ ├── dimen.xml
│ │ │ │ └── strings.xml
│ │ │ └── layout
│ │ │ │ ├── emty_main.xml
│ │ │ │ └── fragment_test.xml
│ │ └── AndroidManifest.xml
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── madisp
│ │ └── pretty
│ │ ├── FragmentsTest.java
│ │ ├── UiThreadRule.java
│ │ └── SanityTest.java
└── build.gradle
├── release.sh
├── LICENSE
├── pretty
├── src
│ └── main
│ │ └── java
│ │ └── com
│ │ └── madisp
│ │ └── pretty
│ │ ├── PrettyLayoutFactory.java
│ │ ├── Decor.java
│ │ ├── Pretty.java
│ │ ├── PrettyLayoutInflater.java
│ │ ├── LayoutFactoryWrapper.java
│ │ └── AttrsDecor.java
└── build.gradle
├── gradlew.bat
├── README.md
└── gradlew
/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'pretty'
2 | include ':pretty', ':samples', ':tests'
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle
2 | local.properties
3 | .idea
4 | .DS_Store
5 | build
6 | *.iml
7 | out
8 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madisp/pretty/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/samples/src/main/assets/Ubuntu-M.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madisp/pretty/HEAD/samples/src/main/assets/Ubuntu-M.ttf
--------------------------------------------------------------------------------
/tests/src/main/java/com/madisp/pretty/FragInLayoutActivity.java:
--------------------------------------------------------------------------------
1 | package com.madisp.pretty;
2 |
3 | public class FragInLayoutActivity {
4 | }
5 |
--------------------------------------------------------------------------------
/samples/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madisp/pretty/HEAD/samples/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/tests/src/main/res/values/dimen.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 |
--------------------------------------------------------------------------------
/samples/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/samples/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Pretty samples
4 |
--------------------------------------------------------------------------------
/tests/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Line 1
4 | Line 2
5 |
--------------------------------------------------------------------------------
/tests/src/main/res/layout/emty_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sun Mar 29 19:28:36 EEST 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.3-all.zip
7 |
--------------------------------------------------------------------------------
/tests/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/tests/src/main/java/com/madisp/pretty/TestFragment.java:
--------------------------------------------------------------------------------
1 | package com.madisp.pretty;
2 |
3 | import android.os.Bundle;
4 | import android.support.v4.app.Fragment;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 |
9 | public class TestFragment extends Fragment {
10 | @Override
11 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
12 | return inflater.inflate(R.layout.fragment_test, container, false);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/samples/src/main/java/com/madisp/pretty/samples/SampleActivity.java:
--------------------------------------------------------------------------------
1 | package com.madisp.pretty.samples;
2 |
3 | import android.os.Bundle;
4 | import android.support.v4.app.FragmentActivity;
5 |
6 | import com.madisp.pretty.Pretty;
7 |
8 | public class SampleActivity extends FragmentActivity {
9 | @Override
10 | protected void onCreate(Bundle savedInstanceState) {
11 | Pretty.wrap(this).with(new FontDecor());
12 | super.onCreate(savedInstanceState);
13 | setContentView(R.layout.main);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/samples/src/main/java/com/madisp/pretty/samples/SampleFragment.java:
--------------------------------------------------------------------------------
1 | package com.madisp.pretty.samples;
2 |
3 | import android.os.Bundle;
4 | import android.support.v4.app.Fragment;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 |
9 | public class SampleFragment extends Fragment {
10 | @Override
11 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
12 | return inflater.inflate(R.layout.main_frag, container, false);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/samples/src/main/res/layout/main.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/tests/src/main/java/com/madisp/pretty/CreatesFragActivity.java:
--------------------------------------------------------------------------------
1 | package com.madisp.pretty;
2 |
3 | import android.os.Bundle;
4 | import android.support.v4.app.FragmentActivity;
5 |
6 | public class CreatesFragActivity extends FragmentActivity {
7 | @Override
8 | protected void onCreate(Bundle savedInstanceState) {
9 | Pretty.wrap(this);
10 | super.onCreate(savedInstanceState);
11 | setContentView(R.layout.emty_main);
12 |
13 | if (savedInstanceState == null) {
14 | getSupportFragmentManager().beginTransaction().add(R.id.main, new TestFragment()).commit();
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/samples/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/samples/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | mavenCentral()
4 | }
5 | dependencies {
6 | classpath 'com.android.tools.build:gradle:1.2.0-beta1'
7 | }
8 | }
9 |
10 | apply plugin: 'com.android.application'
11 |
12 | repositories {
13 | mavenCentral()
14 | }
15 |
16 | dependencies {
17 | // in reality you would use something like this instead of refing the project directly:
18 | // compile 'com.madisp.pretty:pretty:0.1.0'
19 | compile project(':pretty')
20 | compile 'com.android.support:support-v4:22.0.0'
21 | }
22 |
23 | android {
24 | compileSdkVersion 22
25 | buildToolsVersion '22.0.1'
26 |
27 | defaultConfig {
28 | minSdkVersion 15
29 | targetSdkVersion 22
30 | }
31 |
32 | lintOptions {
33 | disable 'MissingPrefix'
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/release.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | KEY_UID=F4DF9A6C
4 | VERSION=0.1.0
5 |
6 | # release into local repo
7 | ./gradlew clean publishMavenJavaPublicationToDryRepository -Prelease=true
8 |
9 | echo ''
10 | echo '=== BUILD DONE, ONTO PUBLISHING ==='
11 | echo ''
12 |
13 | # move into local repo
14 | pushd pretty/build/repo
15 |
16 | # sign all the artifacts in the local repo
17 | read -s -p "GPG key passphrase: " passphrase
18 | echo
19 | for f in com/madisp/pretty/pretty/*/*.{jar,pom}; do
20 | gpg -u $KEY_UID --passphrase $passphrase --sign --detach-sign -a $f
21 | done
22 |
23 | # publish to staging
24 | pushd com/madisp/pretty/pretty/$VERSION
25 | FILES=""
26 | for f in *.{asc,jar,pom}; do
27 | FILES="$f $FILES"
28 | done
29 | FILES=${FILES%" "}
30 | jar -cvf bundle.jar $FILES
31 | popd # com/madisp/pretty/pretty/$VERSION
32 |
33 | popd # pretty/build/repo
34 |
--------------------------------------------------------------------------------
/samples/src/main/java/com/madisp/pretty/samples/FontDecor.java:
--------------------------------------------------------------------------------
1 | package com.madisp.pretty.samples;
2 |
3 | import android.graphics.Typeface;
4 | import android.util.TypedValue;
5 | import android.widget.TextView;
6 |
7 | import com.madisp.pretty.AttrsDecor;
8 |
9 | import org.jetbrains.annotations.NotNull;
10 |
11 | public class FontDecor extends AttrsDecor {
12 | @NotNull
13 | @Override
14 | protected int[] attrs() {
15 | return new int[] { R.attr.typeface_asset };
16 | }
17 |
18 | @NotNull
19 | @Override
20 | protected Class clazz() {
21 | return TextView.class;
22 | }
23 |
24 | @Override
25 | protected void apply(TextView view, int attr, TypedValue value) {
26 | view.setTypeface(Typeface.createFromAsset(view.getResources().getAssets(), value.string.toString()));
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/tests/src/main/res/layout/fragment_test.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
17 |
18 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/tests/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | mavenCentral()
4 | }
5 | dependencies {
6 | classpath 'com.android.tools.build:gradle:1.2.0-beta1'
7 | }
8 | }
9 |
10 | apply plugin: 'com.android.application'
11 | apply plugin: 'jacoco'
12 |
13 | repositories {
14 | mavenCentral()
15 | }
16 |
17 | dependencies {
18 | compile project(':pretty')
19 | compile 'com.android.support:support-v4:22.0.0'
20 | androidTestCompile 'com.android.support.test:testing-support-lib:0.1'
21 | androidTestCompile 'org.assertj:assertj-core:1.7.1'
22 | }
23 |
24 | android {
25 | compileSdkVersion 22
26 | buildToolsVersion '22.0.1'
27 |
28 | defaultConfig {
29 | minSdkVersion 15
30 | targetSdkVersion 22
31 |
32 | testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
33 | }
34 |
35 | lintOptions {
36 | disable 'MissingPrefix'
37 | }
38 |
39 | packagingOptions {
40 | exclude 'LICENSE.txt'
41 | }
42 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2013 Madis Pink
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/samples/src/main/res/layout/main_frag.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
15 |
16 |
22 |
23 |
28 |
29 |
--------------------------------------------------------------------------------
/tests/src/androidTest/java/com/madisp/pretty/FragmentsTest.java:
--------------------------------------------------------------------------------
1 | package com.madisp.pretty;
2 |
3 | import android.app.Activity;
4 | import android.app.Instrumentation;
5 | import android.content.Intent;
6 | import android.support.test.InstrumentationRegistry;
7 | import org.junit.After;
8 | import org.junit.Before;
9 | import org.junit.Test;
10 |
11 | import static org.assertj.core.api.Assertions.assertThat;
12 |
13 | public class FragmentsTest {
14 | private Instrumentation instrumentation;
15 | private Activity activity;
16 |
17 | @Before
18 | public void instrument() {
19 | instrumentation = InstrumentationRegistry.getInstrumentation();
20 | Intent intent = new Intent(instrumentation.getTargetContext(), CreatesFragActivity.class);
21 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
22 | activity = instrumentation.startActivitySync(intent);
23 | }
24 |
25 | @After
26 | public void finish() {
27 | activity.finish();
28 | }
29 |
30 | @Test
31 | public void testCreatesFragActivity() throws Exception {
32 | // test that we have some things in place
33 | assertThat(activity).isNotNull();
34 | assertThat(activity.findViewById(R.id.line1)).isNotNull();
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/pretty/src/main/java/com/madisp/pretty/PrettyLayoutFactory.java:
--------------------------------------------------------------------------------
1 | package com.madisp.pretty;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 |
8 | import org.jetbrains.annotations.NotNull;
9 | import org.jetbrains.annotations.Nullable;
10 |
11 | /**
12 | * A small util class that wraps a layoutinflater and its factory to apply a bunch of decorators.
13 | */
14 | public class PrettyLayoutFactory extends LayoutFactoryWrapper {
15 | Pretty pretty;
16 |
17 | public PrettyLayoutFactory(@NotNull LayoutInflater inflater, @Nullable LayoutInflater.Factory2 base, @NotNull Pretty pretty) {
18 | super(inflater, base);
19 | this.pretty = pretty;
20 | }
21 |
22 | @Override
23 | @Nullable
24 | protected View onViewCreated(@Nullable View view, @Nullable View parent, @NotNull String name, @NotNull Context context, @NotNull AttributeSet attrs) {
25 | if (view == null) {
26 | return null;
27 | }
28 | for (Decor d : pretty.getDecors()) {
29 | d.apply(view, parent, name, context, attrs);
30 | }
31 | return view;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/pretty/src/main/java/com/madisp/pretty/Decor.java:
--------------------------------------------------------------------------------
1 | package com.madisp.pretty;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.View;
6 |
7 | import org.jetbrains.annotations.NotNull;
8 | import org.jetbrains.annotations.Nullable;
9 |
10 | /**
11 | * A class that operates on already constructed views, i.e., decorates them.
12 | */
13 | public interface Decor {
14 | /**
15 | * Decorates the given view.
16 | * This method will be called by Pretty for every {@link android.view.View} created in the layout
17 | * if {@link com.madisp.pretty.Pretty#wrap(android.app.Activity)} was called and the decor added
18 | * with {@link com.madisp.pretty.Pretty#with(Decor)}
19 | * @param view The view to decorate. Never null.
20 | * @param parent The parent view, if available. May be null.
21 | * @param name The name of the tag in the layout file, e.g. {@code TextView}.
22 | * @param context The context where the view was constructed in.
23 | * @param attrs A read-only set of tag attributes.
24 | */
25 | public void apply(@NotNull View view, @Nullable View parent, @NotNull String name, @NotNull Context context, @NotNull AttributeSet attrs);
26 | }
27 |
--------------------------------------------------------------------------------
/tests/src/androidTest/java/com/madisp/pretty/UiThreadRule.java:
--------------------------------------------------------------------------------
1 | package com.madisp.pretty;
2 |
3 | import android.app.Instrumentation;
4 | import android.test.UiThreadTest;
5 | import org.junit.rules.TestRule;
6 | import org.junit.runner.Description;
7 | import org.junit.runners.model.Statement;
8 |
9 | import java.lang.annotation.Annotation;
10 | import java.util.Collection;
11 |
12 | /**
13 | * A JUnit4 rule for Android Instrumentation tests
14 | */
15 | public class UiThreadRule implements TestRule {
16 | private final Instrumentation instrumentation;
17 |
18 | public UiThreadRule(Instrumentation instrumentation) {
19 | this.instrumentation = instrumentation;
20 | }
21 |
22 | @Override
23 | public Statement apply(final Statement statement, Description description) {
24 | Collection annotations = description.getAnnotations();
25 |
26 | for (Annotation annotation : annotations) {
27 | if (UiThreadTest.class.equals(annotation.annotationType())) {
28 | return new Statement() {
29 | @Override
30 | public void evaluate() throws Throwable {
31 | final Throwable[] t = new Throwable[1];
32 | instrumentation.runOnMainSync(new Runnable() {
33 | @Override
34 | public void run() {
35 | try {
36 | statement.evaluate();
37 | } catch (Throwable throwable) {
38 | t[0] = throwable;
39 | }
40 | }
41 | });
42 | if (t[0] != null) {
43 | throw t[0];
44 | }
45 | }
46 | };
47 | }
48 | }
49 | return statement;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/tests/src/androidTest/java/com/madisp/pretty/SanityTest.java:
--------------------------------------------------------------------------------
1 | package com.madisp.pretty;
2 |
3 | import android.app.Activity;
4 | import android.app.Instrumentation;
5 | import android.content.ComponentName;
6 | import android.content.Context;
7 | import android.content.Intent;
8 | import android.content.pm.ActivityInfo;
9 | import android.support.test.InstrumentationRegistry;
10 | import android.test.UiThreadTest;
11 | import android.test.mock.MockApplication;
12 |
13 | import org.junit.Before;
14 | import org.junit.Rule;
15 | import org.junit.Test;
16 |
17 | import static org.assertj.core.api.Assertions.assertThat;
18 |
19 | public class SanityTest {
20 | private Context context;
21 | private Instrumentation instrumentation;
22 |
23 | @Rule
24 | public UiThreadRule onUiThread = new UiThreadRule(InstrumentationRegistry.getInstrumentation());
25 |
26 | @Before
27 | public void instrument() {
28 | context = InstrumentationRegistry.getContext();
29 | instrumentation = InstrumentationRegistry.getInstrumentation();
30 | }
31 |
32 | @Test
33 | public void testSanity() throws Exception {
34 | assertThat(true).isTrue();
35 | assertThat(context).isNotNull();
36 | assertThat(context.getPackageName()).isEqualTo("com.madisp.pretty.test");
37 | }
38 |
39 | @Test
40 | @UiThreadTest
41 | public void testWrapActivity() throws Exception {
42 | Intent intent = new Intent();
43 | intent.setComponent(new ComponentName("com.madisp.pretty", "TestActivity"));
44 |
45 | Activity act = instrumentation.newActivity(
46 | Activity.class,
47 | context,
48 | null,
49 | new MockApplication(),
50 | intent,
51 | new ActivityInfo(),
52 | "",
53 | null,
54 | null,
55 | null);
56 | Pretty.wrap(act);
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/pretty/src/main/java/com/madisp/pretty/Pretty.java:
--------------------------------------------------------------------------------
1 | package com.madisp.pretty;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.util.AttributeSet;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 |
9 | import com.android.internal.policy.impl.PhoneWindow;
10 | import org.jetbrains.annotations.NotNull;
11 |
12 | import java.lang.reflect.Field;
13 | import java.util.ArrayList;
14 | import java.util.Collection;
15 |
16 | /**
17 | * TODO: write a general overview of pretty.
18 | */
19 | public class Pretty {
20 | private final Collection decors = new ArrayList();
21 |
22 | private Pretty(@NotNull final Activity activity) {
23 | // ooh, ugly
24 | try {
25 | Field f = PhoneWindow.class.getDeclaredField("mLayoutInflater");
26 | f.setAccessible(true);
27 | f.set(activity.getWindow(), new PrettyLayoutInflater(this, activity));
28 | } catch (Exception e) {
29 | throw new IllegalStateException("Failed invoking Pretty.wrap on an Activity.", e);
30 | }
31 | }
32 |
33 | /**
34 | * "Infect" a LayoutInflater in an Activity with a new Pretty instance.
35 | * @param activity activity whose LayoutInflater to mangle
36 | * @return An instance of Pretty, see {@link com.madisp.pretty.Pretty#with(Decor)}
37 | */
38 | @NotNull
39 | public static Pretty wrap(@NotNull Activity activity) {
40 | // hide the constructor behind a more stable public "API"
41 | return new Pretty(activity);
42 | }
43 |
44 | /**
45 | * Add a decorator to the filter chain.
46 | * @param decor The decorator to add
47 | * @return Pretty instance used, allows one to chain multiple with calls.
48 | */
49 | @NotNull
50 | public Pretty with(@NotNull Decor decor) {
51 | decors.add(decor);
52 | return this;
53 | }
54 |
55 | /**
56 | * @return The list of decorators registered so far.
57 | */
58 | @NotNull
59 | public Collection getDecors() {
60 | return decors;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/pretty/src/main/java/com/madisp/pretty/PrettyLayoutInflater.java:
--------------------------------------------------------------------------------
1 | package com.madisp.pretty;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.util.AttributeSet;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import com.android.internal.policy.impl.PhoneLayoutInflater;
9 |
10 | public class PrettyLayoutInflater extends PhoneLayoutInflater {
11 |
12 | private LayoutInflater.Factory2 wrappedFactory;
13 | private Pretty pretty;
14 |
15 | public PrettyLayoutInflater(Pretty pretty, final Activity activity) {
16 | super(activity);
17 |
18 | this.pretty = pretty;
19 |
20 | // if the activity is a FragmentActivity from the support lib then lets wrap it
21 | // so the tags still work
22 | try {
23 | Class> fragAct = Class.forName("android.support.v4.app.FragmentActivity");
24 | if (fragAct != null && fragAct.isInstance(activity)) {
25 | // FragmentActivity is a Factory1, not Factory2
26 | wrappedFactory = new LayoutInflater.Factory2() {
27 | @Override
28 | public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
29 | return onCreateView(name, context, attrs);
30 | }
31 |
32 | @Override
33 | public View onCreateView(String name, Context context, AttributeSet attrs) {
34 | return activity.onCreateView(name, context, attrs);
35 | }
36 | };
37 | }
38 | } catch (Exception ignored) { /* ignored */ }
39 | super.setFactory2(new PrettyLayoutFactory(this, wrappedFactory, pretty));
40 | }
41 |
42 | protected PrettyLayoutInflater(LayoutInflater original, Context newContext, LayoutInflater.Factory2 wrappedFactory, Pretty pretty) {
43 | super(original, newContext);
44 | this.pretty = pretty;
45 | super.setFactory2(new PrettyLayoutFactory(this, wrappedFactory, pretty));
46 | }
47 |
48 | @Override
49 | public LayoutInflater cloneInContext(Context newContext) {
50 | return new PrettyLayoutInflater(this, newContext, wrappedFactory, pretty);
51 | }
52 |
53 | @Override
54 | public void setFactory(Factory factory) {
55 | // outright evil, warn here?
56 | }
57 |
58 | @Override
59 | public void setFactory2(Factory2 factory) {
60 | // outright evil, warn here?
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/pretty/src/main/java/com/madisp/pretty/LayoutFactoryWrapper.java:
--------------------------------------------------------------------------------
1 | package com.madisp.pretty;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 |
8 | import org.jetbrains.annotations.NotNull;
9 | import org.jetbrains.annotations.Nullable;
10 |
11 | /**
12 | * A small helper class to wrap a LayoutInflater's factory.
13 | */
14 | public abstract class LayoutFactoryWrapper implements LayoutInflater.Factory2 {
15 | @NotNull
16 | private final LayoutInflater inflater;
17 | @Nullable
18 | private final LayoutInflater.Factory2 base;
19 |
20 | // from com.android.internal.policy.impl.PhoneLayoutInflater
21 | private static final String[] CLASS_PREFIX_LIST = {
22 | "android.widget.",
23 | "android.webkit."
24 | };
25 |
26 | public LayoutFactoryWrapper(@NotNull LayoutInflater inflater, @Nullable LayoutInflater.Factory2 baseFactory) {
27 | this.inflater = inflater;
28 | this.base = baseFactory;
29 | }
30 |
31 | @Override
32 | @Nullable
33 | public View onCreateView(@Nullable View parent, @NotNull String name, @NotNull Context context, @NotNull AttributeSet attrs) {
34 | View v = null;
35 | if (base != null) {
36 | v = base.onCreateView(parent, name, context, attrs);
37 | }
38 | if (v == null) {
39 | // construct a view the same way that android does it
40 | for (String prefix : CLASS_PREFIX_LIST) {
41 | try {
42 | v = inflater.createView(name, prefix, attrs);
43 | if (v != null) {
44 | break;
45 | }
46 | } catch (ClassNotFoundException ignored) {
47 | // let v be null, this means that we don't know how to inflate this view
48 | }
49 | }
50 | }
51 | v = onViewCreated(v, parent, name, context, attrs);
52 | return v;
53 | }
54 |
55 | @Override
56 | @Nullable
57 | public View onCreateView(@NotNull String name, @NotNull Context context, @NotNull AttributeSet attrs) {
58 | return onCreateView(null, name, context, attrs);
59 | }
60 |
61 | @Nullable
62 | protected abstract View onViewCreated(@Nullable View view, @Nullable View parent, @NotNull String name, @NotNull Context context, @NotNull AttributeSet attrs);
63 | }
64 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/pretty/src/main/java/com/madisp/pretty/AttrsDecor.java:
--------------------------------------------------------------------------------
1 | package com.madisp.pretty;
2 |
3 | import android.content.Context;
4 | import android.content.res.TypedArray;
5 | import android.util.AttributeSet;
6 | import android.util.TypedValue;
7 | import android.view.View;
8 |
9 | import org.jetbrains.annotations.NotNull;
10 | import org.jetbrains.annotations.Nullable;
11 |
12 | /**
13 | * A base class for a decorator that transform certain View subtypes with certain attributes. Useful
14 | * when you want to extend standard layout inflation to add your own attributes to system widgets.
15 | * If a view with type {@code View<? extends T>} is inflated and it has one of the attributes
16 | * returned by the {@link AttrsDecor#attrs()} method then {@link com.madisp.pretty.AttrsDecor#apply(android.view.View, int, android.util.TypedValue)}
17 | * will be invoked for that view.
18 | * @param The type or parent type of View that this decorator applies to.
19 | */
20 | public abstract class AttrsDecor implements Decor {
21 | /**
22 | * {@inheritDoc}
23 | */
24 | @Override
25 | public final void apply(@NotNull View view, @Nullable View parent, @NotNull String name, @NotNull Context context, @NotNull AttributeSet attrs) {
26 | if (!clazz().isAssignableFrom(view.getClass())) {
27 | return;
28 | }
29 |
30 | TypedArray values = context.getResources().obtainAttributes(attrs, attrs());
31 | if (values == null) {
32 | return;
33 | }
34 |
35 | TypedValue buf = new TypedValue();
36 | try {
37 | for (int i = 0; i < values.length(); i++) {
38 | if (values.hasValue(i) && values.getValue(i, buf)) {
39 | // inspection disabled as we do know at this point that view can be cast to T
40 | //noinspection unchecked
41 | apply((T)view, attrs()[i], buf);
42 | }
43 | }
44 | } finally {
45 | values.recycle();
46 | }
47 | }
48 |
49 | /**
50 | * Attributes supported by this decorator.
51 | * @return a non-null array of android attr resource ids.
52 | */
53 | @NotNull
54 | protected abstract int[] attrs();
55 |
56 | /**
57 | * The class for the given viewtype. Please be kind and just return the right class here :)
58 | * @return The class/typetoken for T
59 | */
60 | @NotNull
61 | protected abstract Class clazz();
62 |
63 | /**
64 | * This method will be called if a View of type T was inflated and it had one of the attributes
65 | * specified by {@link AttrsDecor#attrs()} set.
66 | * @param view The view object that is being decorated.
67 | * @param attr The attribute resource id (key).
68 | * @param value The attribute value.
69 | */
70 | protected abstract void apply(T view, int attr, TypedValue value);
71 | }
72 |
--------------------------------------------------------------------------------
/pretty/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | mavenCentral()
4 | }
5 | }
6 |
7 | apply plugin: 'java'
8 | apply plugin: 'maven-publish'
9 |
10 | // general project info
11 |
12 | group = 'com.madisp.pretty'
13 | version = '0.1.1'
14 | if (!project.hasProperty('release')) {
15 | version = version + '-SNAPSHOT'
16 | }
17 |
18 | project.sourceCompatibility = '1.6'
19 | tasks.withType(JavaCompile) { options.encoding = 'UTF-8' }
20 |
21 | repositories {
22 | mavenCentral()
23 | }
24 |
25 | configurations {
26 | provided
27 | }
28 |
29 | sourceSets {
30 | main { compileClasspath += configurations.provided }
31 | }
32 |
33 | dependencies {
34 | compile 'org.jetbrains:annotations:13.0'
35 | provided 'org.robolectric:android-all:5.0.0_r2-robolectric-0'
36 | }
37 |
38 | // jar with sources
39 |
40 | task sourceJar(type: Jar) {
41 | from sourceSets.main.allJava
42 | }
43 |
44 | // jar with javadocs
45 |
46 | task javadocs(type: Javadoc) {
47 | source = sourceSets.main.allJava
48 | classpath = configurations.compile
49 | }
50 | task javadocJar(type: Jar, dependsOn: javadocs) {
51 | from javadocs.destinationDir
52 | }
53 |
54 | publishing {
55 | repositories {
56 | maven {
57 | name 'dry'
58 | url "$buildDir/repo"
59 | }
60 | maven {
61 | name 'snapshots'
62 | url 'https://oss.sonatype.org/content/repositories/snapshots'
63 | credentials {
64 | username = System.getenv("SONATYPE_OSS_USER")
65 | password = System.getenv("SONATYPE_OSS_PASS")
66 | }
67 | }
68 | }
69 | publications {
70 | mavenJava(MavenPublication) {
71 | from components.java
72 | artifact sourceJar {
73 | classifier 'sources'
74 | }
75 | artifact javadocJar {
76 | classifier 'javadoc'
77 | }
78 | pom.withXml {
79 | // modify the dependencies
80 | def fixdeps = ['org.jetbrains:annotations':'compile', 'com.google.android:android':'provided']
81 | asNode().dependencies.dependency.each { dep ->
82 | def depId = "${dep.groupId.text()}:${dep.artifactId.text()}"
83 | if (fixdeps[depId]) {
84 | println fixdeps[depId]
85 | println dep.scope.get(0).setValue(fixdeps[depId])
86 | }
87 | }
88 | // add all the extra information
89 | asNode().children().last() + {
90 | resolveStrategy = Closure.DELEGATE_FIRST
91 | name 'pretty'
92 | description 'A convenience library to process View attributes in Android layout files at runtime.'
93 | url 'http://github.com/madisp/pretty'
94 | scm {
95 | url 'http://github.com/madisp/pretty'
96 | connection 'scm:git:git://github.com/madisp/pretty.git'
97 | developerConnection 'scm:git:ssh://git@github.com/madisp/pretty.git'
98 | }
99 | issueManagement {
100 | system 'GitHub'
101 | url 'http://github.com/madisp/pretty/issues'
102 | }
103 | developers {
104 | developer {
105 | id 'madisp'
106 | name 'Madis Pink'
107 | email 'madis.pink@gmail.com'
108 | }
109 | }
110 | licenses {
111 | license {
112 | name 'The MIT License'
113 | url 'http://opensource.org/licenses/MIT'
114 | distribution 'repo'
115 | }
116 | }
117 | }
118 | }
119 | }
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/samples/src/main/assets/ubuntu-font-license-1.0.txt:
--------------------------------------------------------------------------------
1 | Version 1.0
2 |
3 | Preamble
4 |
5 | This licence allows the licensed fonts to be used, studied, modified and redistributed freely. The fonts, including any derivative works, can be bundled, embedded, and redistributed provided the terms of this licence are met. The fonts and derivatives, however, cannot be released under any other licence. The requirement for fonts to remain under this licence does not require any document created using the fonts or their derivatives to be published under this licence, as long as the primary purpose of the document is not to be a vehicle for the distribution of the fonts.
6 |
7 | Definitions
8 |
9 | "Font Software" refers to the set of files released by the Copyright Holder(s) under this licence and clearly marked as such. This may include source files, build scripts and documentation.
10 |
11 | "Original Version" refers to the collection of Font Software components as received under this licence.
12 |
13 | "Modified Version" refers to any derivative made by adding to, deleting, or substituting — in part or in whole — any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
14 |
15 | "Copyright Holder(s)" refers to all individuals and companies who have a copyright ownership of the Font Software.
16 |
17 | "Substantially Changed" refers to Modified Versions which can be easily identified as dissimilar to the Font Software by users of the Font Software comparing the Original Version with the Modified Version.
18 |
19 | To "Propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification and with or without charging a redistribution fee), making available to the public, and in some countries other activities as well.
20 |
21 | Permission & Conditions
22 |
23 | This licence does not grant any rights under trademark law and all such rights are reserved.
24 |
25 | Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to propagate the Font Software, subject to the below conditions:
26 |
27 | Each copy of the Font Software must contain the above copyright notice and this licence. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
28 | The font name complies with the following:
29 | The Original Version must retain its name, unmodified.
30 | Modified Versions which are Substantially Changed must be renamed to avoid use of the name of the Original Version or similar names entirely.
31 | Modified Versions which are not Substantially Changed must be renamed to both
32 | retain the name of the Original Version and
33 | add additional naming elements to distinguish the Modified Version from the Original Version. The name of such Modified Versions must be the name of the Original Version, with "derivative X" where X represents the name of the new work, appended to that name.
34 | The name(s) of the Copyright Holder(s) and any contributor to the Font Software shall not be used to promote, endorse or advertise any Modified Version, except
35 | as required by this licence,
36 | to acknowledge the contribution(s) of the Copyright Holder(s) or
37 | with their explicit written permission.
38 | The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this licence, and must not be distributed under any other licence. The requirement for fonts to remain under this licence does not affect any document created using the Font Software, except any version of the Font Software extracted from a document created using the Font Software may only be distributed under this licence.
39 | Termination
40 |
41 | This licence becomes null and void if any of the above conditions are not met.
42 |
43 | Disclaimer
44 |
45 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
46 |
47 | Ubuntu Font Licence Version 1.0 (plain text)
48 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | pretty
2 | ======
3 |
4 | Pretty is a library that enables one to enhance Android layout inflation without
5 | boilerplate and knowledge about *LayoutInflater* internals. Pretty hooks into
6 | the Android layout inflation so you could add new attributes to existing View
7 | subtypes.
8 |
9 | Example
10 | -------
11 |
12 | Lets take a standard example - using a custom font with TextViews. If you have
13 | used a custom font chances are that you have something like this in your
14 | codebase:
15 |
16 | ```java
17 | TextView text1 = (TextView) findViewById(R.id.text1);
18 | Typeface tf = Typeface.createFromAsset(getResources().getAssets(), "my-font.ttf");
19 | text1.setTypeface(tf);
20 | ```
21 |
22 | This approach doesn't really scale that well once you have a bunch of complex
23 | layouts. This usually results in either creating a `TextView` subclass or some
24 | trickery with walking the view tree and replacing the typeface for all
25 | `TextView` instances.
26 |
27 | Also one shouldn't mix presentation definition (the font)
28 | with logic (the Java code) if at all possible. Wouldn't it be nice if you could
29 | just point to your custom font right there in the layout? E.g.:
30 |
31 | ```xml
32 |
36 | ```
37 |
38 | With some `LayoutInflater` trickery it is actually possible. Pretty does all the
39 | trickery for you so you can focus on the code that matters. Lets write a pretty
40 | decorator that enables us to use a custom attribute to load the typeface.
41 |
42 | First off we need to define our custom attribute in `res/values/attrs.xml`:
43 |
44 | ```xml
45 |
46 |
47 |
48 |
49 | ```
50 |
51 | After having a custom attribute we can reference it in java code through the
52 | `R.attr` class and in our layouts using the `res-auto` package namespace. Now we
53 | can write a decorator that uses the attribute to change the typeface for any
54 | TextView instances.
55 |
56 | We could write a general `Decor` implementation but there is
57 | a base class for writing decorators that work explicitly with attributes -
58 | `AttrsDecor`. Lets use it to implement our `typeface_asset`
59 | attribute:
60 |
61 | ```java
62 | public class FontDecor extends AttrsDecor {
63 | @Override
64 | protected int[] attrs() {
65 | // return the attrs this decorator applies to
66 | return new int[] { R.attr.typeface_asset };
67 | }
68 |
69 | @Override
70 | protected Class clazz() {
71 | // we want to modify all the TextView instances. This includes descendants,
72 | // like Button or EditText.
73 | return TextView.class;
74 | }
75 |
76 | @Override
77 | protected void apply(TextView view, int attr, TypedValue value) {
78 | // this method is called if we have a TextView with any of the attributes
79 | // we previously declared. Usually one would have a switch here but as this
80 | // decorator only supports a single attr we don't need to do that as we know
81 | // it can only be R.attr.typeface_asset.
82 | // So lets just replace the typeface here.
83 | view.setTypeface(Typeface.createFromAsset(view.getResources().getAssets(), value.string.toString()));
84 | }
85 | }
86 | ```
87 |
88 | Now we can use our attribute in a layout:
89 |
90 | ```xml
91 |
98 |
103 |
104 | ```
105 |
106 | Pretty straightforward, right? Now all we need to do is to attach pretty to an
107 | activity so it can take care of all the `LayoutInflater` magic. We also need to
108 | register our new shiny decorator.
109 |
110 | ```java
111 | public class SampleActivity extends Activity {
112 | @Override
113 | protected void onCreate(Bundle savedInstanceState) {
114 | Pretty.wrap(this).with(new FontDecor());
115 | super.onCreate(savedInstanceState);
116 | setContentView(R.layout.main);
117 | }
118 | }
119 | ```
120 |
121 | You can try out this code by checking out the repository and looking at the
122 | `samples` project.
123 |
124 | How pretty works
125 | ----------------
126 |
127 | Pretty does its magic by replacing the view `Factory` in the `LayoutInflater`.
128 | This idea was borrowed from the android support library - thats how the support
129 | library enables one to use the `` tags in OS versions that do not know
130 | about the tag.
131 |
132 | Limitations
133 | -----------
134 |
135 | Currently using attributes with the auto prefix for system widgets raises a lint
136 | error *Unexpected namespace prefix "auto" found for tag T*. Fear not, this is a
137 | red herring. The solution is to suppress that check in your gradle buildfile:
138 |
139 | ```groovy
140 | android {
141 | lintOptions {
142 | disable 'MissingPrefix'
143 | }
144 | }
145 | ```
146 |
147 | License
148 | -------
149 |
150 | Standard MIT. See the LICENSE file.
151 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------