content: /*
   * Copyright (C) 2010 The Android Open Source Project
   *
   * 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 android.app;
  
  import com.android.ide.common.rendering.api.LayoutlibCallback;
  import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
  
  import android.content.Context;
  import android.os.Bundle;
  
  /**
   * Delegate used to provide new implementation of a select few methods of {@link Fragment}
   *
   * Through the layoutlib_create tool, the original  methods of Fragment have been replaced
   * by calls to methods of the same name in this delegate class.
   *
   * The methods being re-implemented are the ones responsible for instantiating Fragment objects.
   * Because the classes of these objects are found in the project, these methods need access to
   * {@link LayoutlibCallback} object. They are however static methods, so the callback is set
   * before the inflation through {@link #setLayoutlibCallback(LayoutlibCallback)}.
   */
  public class Fragment_Delegate {
  
      private static LayoutlibCallback sLayoutlibCallback;
  
      /**
       * Sets the current {@link LayoutlibCallback} to be used to instantiate classes coming
       * from the project being rendered.
       */
      public static void setLayoutlibCallback(LayoutlibCallback layoutlibCallback) {
          sLayoutlibCallback = layoutlibCallback;
      }
  
      /**
       * Like {@link #instantiate(Context, String, Bundle)} but with a null
       * argument Bundle.
       */
      @LayoutlibDelegate
      /*package*/ static Fragment instantiate(Context context, String fname) {
          return instantiate(context, fname, null);
      }
  
      /**
       * Create a new instance of a Fragment with the given class name.  This is
       * the same as calling its empty constructor.
       *
       * @param context The calling context being used to instantiate the fragment.
       * This is currently just used to get its ClassLoader.
       * @param fname The class name of the fragment to instantiate.
       * @param args Bundle of arguments to supply to the fragment, which it
       * can retrieve with {@link Fragment#getArguments()}.  May be null.
       * @return Returns a new fragment instance.
       * @throws Fragment.InstantiationException If there is a failure in instantiating
       * the given fragment class.  This is a runtime exception; it is not
       * normally expected to happen.
       */
      @LayoutlibDelegate
      /*package*/ static Fragment instantiate(Context context, String fname, Bundle args) {
          try {
              if (sLayoutlibCallback != null) {
                  Fragment f = (Fragment) sLayoutlibCallback.loadView(fname,
                          new Class[0], new Object[0]);
  
                  if (args != null) {
                      args.setClassLoader(f.getClass().getClassLoader());
                      f.mArguments = args;
                  }
                  return f;
              }
  
              return null;
          } catch (ClassNotFoundException e) {
              throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname
                      + ": make sure class name exists, is public, and has an"
                      + " empty constructor that is public", e);
          } catch (java.lang.InstantiationException e) {
              throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname
                      + ": make sure class name exists, is public, and has an"
                      + " empty constructor that is public", e);
          } catch (IllegalAccessException e) {
              throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname
                      + ": make sure class name exists, is public, and has an"
                      + " empty constructor that is public", e);
          } catch (Exception e) {
              throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname
                      + ": make sure class name exists, is public, and has an"
                      + " empty constructor that is public", e);
          }
      }
  }
  