001/**
002 * Copyright 2013 John Ericksen
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *    http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.androidtransfuse.analysis;
017
018import org.androidtransfuse.adapter.ASTType;
019import org.androidtransfuse.annotations.Data;
020import org.androidtransfuse.annotations.Intent;
021import org.androidtransfuse.annotations.IntentFilter;
022import org.androidtransfuse.annotations.IntentFilters;
023import org.androidtransfuse.model.manifest.Action;
024import org.androidtransfuse.model.manifest.Category;
025
026import javax.inject.Inject;
027import javax.inject.Provider;
028import java.util.ArrayList;
029import java.util.List;
030
031import static org.androidtransfuse.util.AnnotationUtil.checkBlank;
032import static org.androidtransfuse.util.AnnotationUtil.checkDefault;
033
034/**
035 * Factory to build the IntentFilter metadata from an annotated class.
036 *
037 * @author John Ericksen
038 */
039public class IntentFilterFactory {
040
041    private final Provider<org.androidtransfuse.model.manifest.IntentFilter> intentFilterProvider;
042    private final Provider<Action> actionProvider;
043    private final Provider<Category> categoryProvider;
044    private final Provider<org.androidtransfuse.model.manifest.Data> dataProvider;
045
046    @Inject
047    public IntentFilterFactory(Provider<org.androidtransfuse.model.manifest.IntentFilter> intentFilterProvider, Provider<Action> actionProvider, Provider<Category> categoryProvider, Provider<org.androidtransfuse.model.manifest.Data> dataProvider) {
048        this.intentFilterProvider = intentFilterProvider;
049        this.actionProvider = actionProvider;
050        this.categoryProvider = categoryProvider;
051        this.dataProvider = dataProvider;
052    }
053
054    public List<org.androidtransfuse.model.manifest.IntentFilter> buildIntentFilters(ASTType astType) {
055
056        IntentFilters intentFilters = astType.getAnnotation(IntentFilters.class);
057        IntentFilter intentFilter = astType.getAnnotation(IntentFilter.class);
058        Intent intent = astType.getAnnotation(Intent.class);
059        Data data = astType.getAnnotation(Data.class);
060
061        List<org.androidtransfuse.model.manifest.IntentFilter> convertedIntentFilters = new ArrayList<org.androidtransfuse.model.manifest.IntentFilter>();
062
063        if(intentFilters != null){
064            for (IntentFilter filter : intentFilters.value()) {
065                convertedIntentFilters.add(convertIntentFilter(filter));
066            }
067        }
068
069        org.androidtransfuse.model.manifest.IntentFilter resultIntentFilter = null;
070        if (intentFilter != null) {
071            resultIntentFilter = convertIntentFilter(intentFilter);
072            convertedIntentFilters.add(resultIntentFilter);
073        }
074        if (intent != null) {
075            if (resultIntentFilter == null) {
076                resultIntentFilter = intentFilterProvider.get();
077                convertedIntentFilters.add(resultIntentFilter);
078            }
079
080            addIntent(intent, resultIntentFilter);
081        }
082        if(data != null){
083            if(resultIntentFilter == null){
084                resultIntentFilter = intentFilterProvider.get();
085                convertedIntentFilters.add(resultIntentFilter);
086            }
087            addData(data, resultIntentFilter);
088        }
089
090        return convertedIntentFilters;
091    }
092
093    private org.androidtransfuse.model.manifest.IntentFilter convertIntentFilter(IntentFilter intentFilter){
094        org.androidtransfuse.model.manifest.IntentFilter resultIntentFilter = intentFilterProvider.get();
095
096        resultIntentFilter.setIcon(checkBlank(intentFilter.icon()));
097        resultIntentFilter.setLabel(checkBlank(intentFilter.label()));
098        resultIntentFilter.setPriority(checkDefault(intentFilter.priority(), -1));
099
100        for (Intent intentAnnotation : intentFilter.value()) {
101            addIntent(intentAnnotation, resultIntentFilter);
102        }
103
104        for (Data dataAnnotation : intentFilter.data()){
105            addData(dataAnnotation, resultIntentFilter);
106        }
107
108        return resultIntentFilter;
109    }
110
111    private void addIntent(Intent intentAnnotation, org.androidtransfuse.model.manifest.IntentFilter intentFilter) {
112        switch (intentAnnotation.type()) {
113            case ACTION:
114                Action action = actionProvider.get();
115                action.setName(intentAnnotation.name());
116                intentFilter.getActions().add(action);
117                break;
118            case CATEGORY:
119                Category category = categoryProvider.get();
120                category.setName(intentAnnotation.name());
121                intentFilter.getCategories().add(category);
122                break;
123            default:
124                //noop
125                break;
126        }
127    }
128
129    private void addData(Data dataAnnotation, org.androidtransfuse.model.manifest.IntentFilter intentFilter) {
130        org.androidtransfuse.model.manifest.Data data = dataProvider.get();
131
132        data.setHost(checkBlank(dataAnnotation.host()));
133        data.setPath(checkBlank(dataAnnotation.path()));
134        Integer port = checkDefault(dataAnnotation.port(), -1);
135        data.setPort(port == null? null : port.toString());
136        data.setMimeType(checkBlank(dataAnnotation.mimeType()));
137        data.setPathPattern(checkBlank(dataAnnotation.pathPattern()));
138        data.setPathPrefix(checkBlank(dataAnnotation.pathPrefix()));
139        data.setScheme(checkBlank(dataAnnotation.scheme()));
140
141        intentFilter.getData().add(data);
142    }
143}