package org.itsnat.droid.impl.xmlinflater.layout; import android.view.View; import org.itsnat.droid.ItsNatDroidException; import org.itsnat.droid.impl.browser.serveritsnat.NodeToInsertImpl; import org.itsnat.droid.impl.dom.DOMAttr; import org.itsnat.droid.impl.dom.layout.DOMElemView; import org.itsnat.droid.impl.util.MiscUtil; import org.itsnat.droid.impl.xmlinflater.ClassDescMgr; import org.itsnat.droid.impl.xmlinflater.XMLInflaterRegistry; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescViewBased; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescViewUnknown; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_Include; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_gesture_GestureOverlayView; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_view_View; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_view_ViewGroup; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_view_ViewStub; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_AbsListView; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_AbsSeekBar; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_AbsSpinner; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_AdapterViewAnimator; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_AdapterViewFlipper; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_AnalogClock; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_AutoCompleteTextView; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_CalendarView; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_CheckedTextView; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_Chronometer; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_CompoundButton; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_DatePicker; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_ExpandableListView; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_FrameLayout; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_Gallery; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_GridLayout; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_GridView; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_HorizontalScrollView; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_ImageView; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_LinearLayout; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_ListView; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_ProgressBar; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_RadioGroup; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_RatingBar; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_RelativeLayout; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_ScrollView; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_SearchView; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_SeekBar; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_SlidingDrawer; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_Spinner; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_Switch; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_TabWidget; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_TableLayout; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_TextView; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_ToggleButton; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_ViewAnimator; import org.itsnat.droid.impl.xmlinflater.layout.classtree.ClassDescView_widget_ViewFlipper; /** * Created by jmarranz on 30/04/14. */ public class ClassDescViewMgr extends ClassDescMgr<ClassDescViewBased> { public final String[] implicitImports = new String[] { "android.view.", "android.widget." }; // Es para añadir imports implícitos tal y como hace Android en los layouts public ClassDescViewMgr(XMLInflaterRegistry parent) { super(parent); initClassDesc(); } public ClassDescViewBased get(NodeToInsertImpl node) { String className = node.getName(); if ("view".equals(className)) { DOMAttr classAttr = node.getDOMAttribute(null, "class"); if (classAttr == null) throw new ItsNatDroidException("Expecified <view> but missing class attribute"); String classAttrValue = classAttr.getValue(); return get(className,classAttrValue); } return get(className,null); } public ClassDescViewBased get(DOMElemView domElemView) { String className = domElemView.getTagName(); if ("view".equals(className)) { DOMAttr classAttr = domElemView.getDOMAttribute(null, "class"); if (classAttr == null) throw new ItsNatDroidException("Expecified <view> but missing class attribute"); String classAttrValue = classAttr.getValue(); return get(className,classAttrValue); } return get(className,null); } @Override public ClassDescViewBased get(String className) { return get(className,null); } private ClassDescViewBased get(String className,String classAttrValue) { if (classAttrValue == null) { ClassDescViewBased classDesc = classes.get(className); if (classDesc != null) return classDesc; if (isSimpleClassName(className)) { for (String implicit : implicitImports) { String classNameCandidate = implicit + className; classDesc = classes.get(classNameCandidate); if (classDesc != null) return classDesc; } // Hay algún caso como CheckBox que no está registrado en ItsNat Droid porque NO tiene atributos específicos (la clase base sí), luego al llamarse a resolveClass() se intentará de nuevo cargar // usando los implicit imports pues es posible que exista (puede ser un componente no existente en API 15 pero sí en superiores) // También puede ser un custom view con package por defecto (sin package) } } else if ("view".equals(className)) { // Caso <view class="className"> className = classAttrValue; } else throw MiscUtil.internalError(); Class<? extends View> nativeClass = null; try { nativeClass = resolveClass(className); } catch (ClassNotFoundException ex) { throw new ItsNatDroidException(ex); } ClassDescViewBased classDesc = get(nativeClass); return classDesc; } public ClassDescViewBased get(Class<? extends View> nativeClass) { ClassDescViewBased classDesc = classes.get(nativeClass.getName()); if (classDesc == null) classDesc = registerUnknown(nativeClass); return classDesc; // Nunca es nulo } public ClassDescViewBased get(View nativeObj) { Class<? extends View> nativeClass = nativeObj.getClass(); return get(nativeClass); } private ClassDescViewBased registerUnknown(Class<? extends View> nativeClass) { String className = nativeClass.getName(); // Tenemos que obtener los ClassDescViewBase de las clases base para que podamos saber lo más posible y procesar por ej atributos @SuppressWarnings("unchecked") Class<? extends View> superClass = (Class<? extends View>)nativeClass.getSuperclass(); ClassDescViewBased parentClassDesc = get(superClass); // Si fuera también unknown se llamará recursivamente de nuevo a este método ClassDescViewBased classDesc = createClassDescUnknown(className, parentClassDesc); classes.put(nativeClass.getName(), classDesc); return classDesc; } @SuppressWarnings("unchecked") private Class<? extends View> resolveClass(String viewName) throws ClassNotFoundException { if (isSimpleClassName(viewName)) { for(int i = 0; i < implicitImports.length; i++) { String implicit = implicitImports[i]; if (i + 1 == implicitImports.length) // El último, si falla dejamos que haya excepción { return resolveClass(implicit + viewName); } else { try { return resolveClass(implicit + viewName); } catch (ClassNotFoundException e) { continue; } } } throw MiscUtil.internalError(); // Nunca se llega aqui } else { return (Class<? extends View>)Class.forName(viewName); } } private ClassDescViewBased createClassDescUnknown(String className,ClassDescViewBased parentClass) { return new ClassDescViewUnknown(this,className,parentClass); } public boolean isSimpleClassName(String className) { return className.indexOf('.') == -1; } @Override protected void initClassDesc() { ClassDescView_view_View view_View = new ClassDescView_view_View(this); addClassDesc(view_View); ClassDescView_widget_AnalogClock widget_AnalogClock = new ClassDescView_widget_AnalogClock(this,view_View); addClassDesc(widget_AnalogClock); ClassDescView_widget_ImageView widget_ImageView = new ClassDescView_widget_ImageView(this,view_View); addClassDesc(widget_ImageView); // android.widget.ImageButton no tiene atributos // android.widget.ZoomButton no tiene atributos ni derivadas // KeyboardView tiene escaso interés, para el futuro // android.app.MediaRouteButton no tiene atributos in derivadas ClassDescView_widget_ProgressBar widget_ProgressBar = new ClassDescView_widget_ProgressBar(this,view_View); addClassDesc(widget_ProgressBar); ClassDescView_widget_AbsSeekBar widget_AbsSeekBar = new ClassDescView_widget_AbsSeekBar(this,widget_ProgressBar); addClassDesc(widget_AbsSeekBar); ClassDescView_widget_RatingBar widget_RatingBar = new ClassDescView_widget_RatingBar(this,widget_AbsSeekBar); addClassDesc(widget_RatingBar); ClassDescView_widget_SeekBar widget_SeekBar = new ClassDescView_widget_SeekBar(this,widget_AbsSeekBar); addClassDesc(widget_SeekBar); // android.widget.Space no tiene atributos ni derivadas // android.view.SurfaceView no tiene atributos // android.opengl.GLSurfaceView no tiene atributos ni derivadas // android.widget.VideoView no tiene atributos ni derivadas // android.support.design.widget.TabItem implementar??? ClassDescView_widget_TextView widget_TextView = new ClassDescView_widget_TextView(this,view_View); addClassDesc(widget_TextView); init_widget_TextView_subClasses(widget_TextView); // android.view.TextureView no tiene atributos ni derivadas ClassDescView_view_ViewGroup view_ViewGroup = new ClassDescView_view_ViewGroup(this,view_View); addClassDesc(view_ViewGroup); init_view_ViewGroup_subClasses(view_ViewGroup); ClassDescView_view_ViewStub view_ViewStub = new ClassDescView_view_ViewStub(this,view_View); addClassDesc(view_ViewStub); } private void init_widget_TextView_subClasses(ClassDescView_widget_TextView widget_TextView) { ClassDescViewBased widget_Button = new ClassDescViewBased(this,"android.widget.Button",widget_TextView); // no tiene atributos addClassDesc(widget_Button); ClassDescView_widget_CompoundButton widget_CompoundButton = new ClassDescView_widget_CompoundButton(this,widget_Button); addClassDesc(widget_CompoundButton); // CheckBox no tiene atributos ni derivadas // RadioButton no tiene atributos ni derivadas y se testea indirectamente en RadioGroup ClassDescView_widget_Switch widget_Switch = new ClassDescView_widget_Switch(this,widget_CompoundButton); addClassDesc(widget_Switch); ClassDescView_widget_ToggleButton widget_ToggleButton = new ClassDescView_widget_ToggleButton(this,widget_CompoundButton); addClassDesc(widget_ToggleButton); ClassDescView_widget_CheckedTextView widget_CheckedTextView = new ClassDescView_widget_CheckedTextView(this,widget_TextView); addClassDesc(widget_CheckedTextView); ClassDescView_widget_Chronometer widget_Chronometer = new ClassDescView_widget_Chronometer(this,widget_TextView); addClassDesc(widget_Chronometer); // android.widget.DigitalClock no tiene atributos y está deprecated en level 17 ClassDescViewBased widget_EditText = new ClassDescViewBased(this,"android.widget.EditText",widget_TextView); // no tiene atributos addClassDesc(widget_EditText); ClassDescView_widget_AutoCompleteTextView widget_AutoCompleteTextView = new ClassDescView_widget_AutoCompleteTextView(this,widget_EditText); addClassDesc(widget_AutoCompleteTextView); // android.widget.MultiAutoCompleteTextView no tiene atributos ni derivadas // android.inputmethodservice.ExtractEditText no tiene atributos ni derivadas // android.widget.TextClock es Level 17 } private void init_view_ViewGroup_subClasses(ClassDescView_view_ViewGroup view_ViewGroup) { // AbsoluteLayout es deprecated en level 3 y su derivada (WebView) no tiene atributos ClassDescViewBased widget_AdapterView = new ClassDescViewBased(this,"android.widget.AdapterView",view_ViewGroup); // AdapterView no tiene atributos addClassDesc(widget_AdapterView); ClassDescView_widget_AbsListView widget_AbsListView = new ClassDescView_widget_AbsListView(this,widget_AdapterView); addClassDesc(widget_AbsListView); ClassDescView_widget_GridView widget_GridView = new ClassDescView_widget_GridView(this,widget_AbsListView); addClassDesc(widget_GridView); ClassDescView_widget_ListView widget_ListView = new ClassDescView_widget_ListView(this,widget_AbsListView); addClassDesc(widget_ListView); ClassDescView_widget_ExpandableListView widget_ExListView = new ClassDescView_widget_ExpandableListView(this,widget_ListView); addClassDesc(widget_ExListView); ClassDescView_widget_AbsSpinner widget_AbsSpinner = new ClassDescView_widget_AbsSpinner(this,widget_AdapterView); addClassDesc(widget_AbsSpinner); ClassDescView_widget_Gallery widget_Gallery = new ClassDescView_widget_Gallery(this,widget_AbsSpinner); // deprecated en level 16 pero como la tenemos hecha la conservamos addClassDesc(widget_Gallery); ClassDescView_widget_Spinner widget_Spinner = new ClassDescView_widget_Spinner(this,widget_AbsSpinner); addClassDesc(widget_Spinner); ClassDescView_widget_AdapterViewAnimator widget_AdapterViewAnimator = new ClassDescView_widget_AdapterViewAnimator(this,widget_AdapterView); addClassDesc(widget_AdapterViewAnimator); ClassDescView_widget_AdapterViewFlipper widget_AdapterViewFlipper = new ClassDescView_widget_AdapterViewFlipper(this,widget_AdapterViewAnimator); addClassDesc(widget_AdapterViewFlipper); // android.widget.StackView no tiene atributos ni derivadas // android.app.FragmentBreadCrumbs no tiene atributos ni derivadas y está deprecated en level 21 ClassDescView_widget_FrameLayout widget_FrameLayout = new ClassDescView_widget_FrameLayout(this,view_ViewGroup); addClassDesc(widget_FrameLayout); ClassDescView_Include include = new ClassDescView_Include(this,widget_FrameLayout); addClassDesc(include); // android.appwidget.AppWidgetHostView no tiene atributos ni ClassDescView_widget_CalendarView widget_CalendarView = new ClassDescView_widget_CalendarView(this,widget_FrameLayout); addClassDesc(widget_CalendarView); ClassDescView_widget_DatePicker widget_DatePicker = new ClassDescView_widget_DatePicker(this,widget_FrameLayout); addClassDesc(widget_DatePicker); ClassDescView_gesture_GestureOverlayView widget_GestureOverlayView = new ClassDescView_gesture_GestureOverlayView(this,widget_FrameLayout); addClassDesc(widget_GestureOverlayView); ClassDescView_widget_HorizontalScrollView widget_HorizontalScrollView = new ClassDescView_widget_HorizontalScrollView(this,widget_FrameLayout); addClassDesc(widget_HorizontalScrollView); // android.widget.MediaController no tiene atributos ClassDescView_widget_ScrollView widget_ScrollView = new ClassDescView_widget_ScrollView(this,widget_FrameLayout); addClassDesc(widget_ScrollView); // android.widget.TabHost no tiene atributos // android.widget.TimePicker tiene un atributo android:timePickerMode pero es level 22 ClassDescView_widget_ViewAnimator widget_ViewAnimator = new ClassDescView_widget_ViewAnimator(this,widget_FrameLayout); addClassDesc(widget_ViewAnimator); ClassDescView_widget_ViewFlipper widget_ViewFlipper = new ClassDescView_widget_ViewFlipper(this,widget_ViewAnimator); addClassDesc(widget_ViewFlipper); // android.widget.ViewSwitcher no tiene atributos // android.widget.ImageSwitcher no tiene atributos // android.widget.TextSwitcher no tiene atributos ClassDescView_widget_GridLayout widget_GridLayout = new ClassDescView_widget_GridLayout(this,view_ViewGroup); addClassDesc(widget_GridLayout); ClassDescView_widget_LinearLayout widget_LinearLayout = new ClassDescView_widget_LinearLayout(this,view_ViewGroup); addClassDesc(widget_LinearLayout); // android.widget.ActionMenuView es level 21 // android.widget.NumberPicker no tiene atributos ClassDescView_widget_RadioGroup widget_RadioGroup = new ClassDescView_widget_RadioGroup(this,widget_LinearLayout); addClassDesc(widget_RadioGroup); ClassDescView_widget_SearchView widget_SearchView = new ClassDescView_widget_SearchView(this,widget_LinearLayout); addClassDesc(widget_SearchView); ClassDescView_widget_TabWidget widget_TabWidget = new ClassDescView_widget_TabWidget(this,widget_LinearLayout); addClassDesc(widget_TabWidget); ClassDescView_widget_TableLayout widget_TableLayout = new ClassDescView_widget_TableLayout(this,widget_LinearLayout); addClassDesc(widget_TableLayout); // android.widget.TableRow no tiene atributos ni derivadas // android.widget.ZoomControls no tiene atributos ni derivadas ClassDescView_widget_RelativeLayout widget_RelativeLayout = new ClassDescView_widget_RelativeLayout(this,view_ViewGroup); addClassDesc(widget_RelativeLayout); // android.widget.DialerFilter no tiene atributos // android.widget.TwoLineListItem tiene un atributo android:mode no implementado y la clase es deprecated en level 17 ClassDescView_widget_SlidingDrawer widget_SlidingDrawer = new ClassDescView_widget_SlidingDrawer(this,view_ViewGroup); // This class was deprecated in API level 17 addClassDesc(widget_SlidingDrawer); // android.widget.Toolbar es level 21 // android.media.tv.TvView es level 21 } }