| /******************************************************************************* |
| * Copyright (c) 2010, 2017 BestSolution.at and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation |
| * Sopot Cela <sopotcela@gmail.com> |
| * Patrik Suzzi <psuzzi@gmail.com> - Bug 421066, 466491 |
| ******************************************************************************/ |
| package org.eclipse.e4.internal.tools.wizards.classes; |
| |
| import java.beans.PropertyChangeListener; |
| import java.beans.PropertyChangeSupport; |
| |
| import org.eclipse.core.databinding.Binding; |
| import org.eclipse.core.databinding.DataBindingContext; |
| import org.eclipse.core.databinding.UpdateValueStrategy; |
| import org.eclipse.core.databinding.beans.BeanProperties; |
| import org.eclipse.core.databinding.conversion.Converter; |
| import org.eclipse.core.databinding.observable.value.IObservableValue; |
| import org.eclipse.core.databinding.validation.IValidator; |
| import org.eclipse.core.databinding.validation.MultiValidator; |
| import org.eclipse.core.databinding.validation.ValidationStatus; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IFolder; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IWorkspaceRoot; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.e4.internal.tools.Messages; |
| import org.eclipse.e4.internal.tools.ToolsPlugin; |
| import org.eclipse.jdt.core.ICompilationUnit; |
| import org.eclipse.jdt.core.IJavaElement; |
| import org.eclipse.jdt.core.IJavaModel; |
| import org.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jdt.core.IPackageFragment; |
| import org.eclipse.jdt.core.IPackageFragmentRoot; |
| import org.eclipse.jdt.core.JavaConventions; |
| import org.eclipse.jdt.core.JavaCore; |
| import org.eclipse.jdt.core.JavaModelException; |
| import org.eclipse.jdt.internal.ui.JavaPlugin; |
| import org.eclipse.jdt.internal.ui.wizards.NewWizardMessages; |
| import org.eclipse.jdt.internal.ui.wizards.TypedElementSelectionValidator; |
| import org.eclipse.jdt.internal.ui.wizards.TypedViewerFilter; |
| import org.eclipse.jdt.ui.JavaElementComparator; |
| import org.eclipse.jdt.ui.JavaElementLabelProvider; |
| import org.eclipse.jdt.ui.StandardJavaElementContentProvider; |
| import org.eclipse.jface.databinding.swt.ISWTObservableValue; |
| import org.eclipse.jface.databinding.swt.IWidgetValueProperty; |
| import org.eclipse.jface.databinding.swt.WidgetProperties; |
| import org.eclipse.jface.databinding.wizard.WizardPageSupport; |
| import org.eclipse.jface.dialogs.IDialogSettings; |
| import org.eclipse.jface.resource.ImageDescriptor; |
| import org.eclipse.jface.viewers.ILabelProvider; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.viewers.Viewer; |
| import org.eclipse.jface.viewers.ViewerFilter; |
| import org.eclipse.jface.window.Window; |
| import org.eclipse.jface.wizard.WizardPage; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.Button; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Text; |
| import org.eclipse.ui.dialogs.ElementListSelectionDialog; |
| import org.eclipse.ui.dialogs.ElementTreeSelectionDialog; |
| |
| @SuppressWarnings("restriction") |
| public abstract class AbstractNewClassPage extends WizardPage { |
| private static final String BUNDLECLASS = "bundleclass://"; //$NON-NLS-1$ |
| private static final String FRAGMENT_ROOT = "fragmentRoot"; //$NON-NLS-1$ |
| public static final String PACKAGE_FRAGMENT = "packageFragment"; //$NON-NLS-1$ |
| public static final String PROPERTY_NAME = "name"; //$NON-NLS-1$ |
| |
| /** Name of the setting section for the new class wizard */ |
| private static final String SETTING_SECTION_NEW_CLASS = "org.eclipse.e4.tools.wizards.newclass"; //$NON-NLS-1$ |
| /** The package dialog setting */ |
| private static final String SETTING_PACKAGE = "package"; //$NON-NLS-1$ |
| |
| public static class JavaClass { |
| |
| protected PropertyChangeSupport support = new PropertyChangeSupport(this); |
| |
| private IPackageFragmentRoot fragmentRoot; |
| private IPackageFragment packageFragment; |
| private String name; |
| |
| public JavaClass(IPackageFragmentRoot fragmentRoot) { |
| this.fragmentRoot = fragmentRoot; |
| } |
| |
| public IPackageFragmentRoot getFragmentRoot() { |
| return fragmentRoot; |
| } |
| |
| public void setFragmentRoot(IPackageFragmentRoot fragmentRoot) { |
| support.firePropertyChange(FRAGMENT_ROOT, this.fragmentRoot, this.fragmentRoot = fragmentRoot); |
| } |
| |
| public IPackageFragment getPackageFragment() { |
| return packageFragment; |
| } |
| |
| public void setPackageFragment(IPackageFragment packageFragment) { |
| support.firePropertyChange(PACKAGE_FRAGMENT, this.packageFragment, this.packageFragment = packageFragment); |
| } |
| |
| public String getName() { |
| return name; |
| } |
| |
| public void setName(String name) { |
| support.firePropertyChange(PROPERTY_NAME, this.name, this.name = name); |
| } |
| |
| public void addPropertyChangeListener(PropertyChangeListener listener) { |
| support.addPropertyChangeListener(listener); |
| } |
| |
| public void removePropertyChangeListener(PropertyChangeListener listener) { |
| support.removePropertyChangeListener(listener); |
| } |
| |
| public static boolean exists(IPackageFragmentRoot pFragmentRoot, IPackageFragment pPackageFragment, String pName) { |
| |
| if (pFragmentRoot == null) { |
| return false; |
| } |
| |
| final String cuName = pName + ".java"; //$NON-NLS-1$ |
| IFile file; |
| |
| if (pPackageFragment != null) { |
| final ICompilationUnit unit = pPackageFragment.getCompilationUnit(cuName); |
| final IResource resource = unit.getResource(); |
| file = (IFile) resource; |
| } else { |
| final IFolder p = (IFolder) pFragmentRoot.getResource(); |
| file = p.getFile(cuName); |
| } |
| return file.exists(); |
| } |
| } |
| |
| private JavaClass clazz; |
| private IPackageFragmentRoot froot; |
| private final IWorkspaceRoot fWorkspaceRoot; |
| private String initialString; |
| private String initialPackage; |
| |
| protected AbstractNewClassPage(String pageName, String title, String description, IPackageFragmentRoot froot, |
| IWorkspaceRoot fWorkspaceRoot) { |
| super(pageName); |
| this.froot = froot; |
| this.fWorkspaceRoot = fWorkspaceRoot; |
| |
| setTitle(title); |
| setDescription(description); |
| } |
| |
| protected AbstractNewClassPage(String pageName, String title, String description, IPackageFragmentRoot froot, |
| IWorkspaceRoot fWorkspaceRoot, String initialString) { |
| this(pageName, title, description, froot, fWorkspaceRoot); |
| this.initialString = initialString; |
| } |
| |
| /** |
| * The wizard owning this page is responsible for calling this method with |
| * the current selection. The selection is used to initialize the fields of |
| * the wizard page. |
| * |
| * @param selection |
| * used to initialize the fields |
| */ |
| public void init(IStructuredSelection selection) { |
| if (selection != null && !selection.isEmpty() && selection.getFirstElement() != null |
| && selection.getFirstElement() instanceof IPackageFragment) { |
| final IPackageFragment pkg = (IPackageFragment) selection.getFirstElement(); |
| initialPackage = pkg.getElementName(); |
| } else { |
| String settingPackage = getDialogSettings().get(SETTING_PACKAGE); |
| if (settingPackage != null) { |
| initialPackage = settingPackage; |
| } |
| } |
| } |
| |
| /** |
| * Gets called if the wizard is finished |
| */ |
| public void performFinish() { |
| String packageName = clazz.getPackageFragment().getElementName(); |
| getDialogSettings().put(SETTING_PACKAGE, packageName); |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @see org.eclipse.jface.wizard.WizardPage#getDialogSettings() |
| */ |
| @Override |
| protected IDialogSettings getDialogSettings() { |
| final IDialogSettings mainSettings = ToolsPlugin.getDefault().getDialogSettings(); |
| IDialogSettings settingsSection = mainSettings.getSection(SETTING_SECTION_NEW_CLASS); |
| if (settingsSection == null) { |
| settingsSection = mainSettings.addNewSection(SETTING_SECTION_NEW_CLASS); |
| } |
| return settingsSection; |
| } |
| |
| @SuppressWarnings("unchecked") |
| @Override |
| public void createControl(Composite parent) { |
| final Image img = new Image(parent.getDisplay(), getClass().getClassLoader().getResourceAsStream( |
| "/icons/full/wizban/newclass_wiz.png")); //$NON-NLS-1$ |
| setImageDescriptor(ImageDescriptor.createFromImage(img)); |
| |
| parent.addDisposeListener(e -> { |
| img.dispose(); |
| setImageDescriptor(null); |
| }); |
| |
| parent = new Composite(parent, SWT.NULL); |
| parent.setLayoutData(new GridData(GridData.FILL_BOTH)); |
| parent.setLayout(new GridLayout(3, false)); |
| |
| clazz = createInstance(); |
| if (froot != null && initialString != null) { |
| clazz.setPackageFragment(froot.getPackageFragment(parseInitialStringForPackage(initialString) == null ? "" //$NON-NLS-1$ |
| : parseInitialStringForPackage(initialString))); |
| clazz.setName(parseInitialStringForClassName(initialString)); |
| } else if (froot != null && initialPackage != null) { |
| clazz.setPackageFragment(froot.getPackageFragment(initialPackage)); |
| } |
| final DataBindingContext dbc = new DataBindingContext(); |
| WizardPageSupport.create(this, dbc); |
| |
| { |
| final Label l = new Label(parent, SWT.NONE); |
| l.setText(Messages.AbstractNewClassPage_SourceFolder); |
| |
| final Text t = new Text(parent, SWT.BORDER); |
| t.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
| t.setEditable(false); |
| |
| final Binding bd = dbc.bindValue( |
| WidgetProperties.text().observe(t), BeanProperties.value(FRAGMENT_ROOT).observe(clazz), |
| new UpdateValueStrategy<>().setBeforeSetValidator(new PFRootValidator()), |
| new UpdateValueStrategy<>().setConverter(new PackageFragmentRootToStringConverter()) |
| ); |
| |
| final Button b = new Button(parent, SWT.PUSH); |
| b.setText(Messages.AbstractNewClassPage_Browse); |
| b.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| final IPackageFragmentRoot root = choosePackageRoot(); |
| if (root != null) { |
| froot = root; |
| clazz.setFragmentRoot(root); |
| } |
| bd.updateModelToTarget(); |
| } |
| }); |
| } |
| |
| final Text tClassPackage; |
| { |
| final Label l = new Label(parent, SWT.NONE); |
| l.setText(Messages.AbstractNewClassPage_Package); |
| tClassPackage = new Text(parent, SWT.BORDER); |
| tClassPackage.setEditable(true); |
| tClassPackage.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
| final Binding bd = dbc.bindValue( |
| WidgetProperties.text(SWT.Modify).observe(tClassPackage), |
| BeanProperties.value(PACKAGE_FRAGMENT).observe(clazz), |
| new UpdateValueStrategy<>().setConverter(new StringToPackageFragmentConverter(clazz)), |
| new UpdateValueStrategy<>().setConverter(new PackageFragmentToStringConverter())); |
| |
| final Button b = new Button(parent, SWT.PUSH); |
| b.setText(Messages.AbstractNewClassPage_Browse); |
| b.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| final IPackageFragment fragment = choosePackage(); |
| if (fragment != null) { |
| clazz.setPackageFragment(fragment); |
| } |
| bd.updateModelToTarget(); // TODO Find out why this is needed |
| } |
| }); |
| } |
| |
| final Text tClassName; |
| { |
| final IWidgetValueProperty textProp = WidgetProperties.text(SWT.Modify); |
| |
| final Label l = new Label(parent, SWT.NONE); |
| l.setText(Messages.AbstractNewClassPage_Name); |
| |
| tClassName = new Text(parent, SWT.BORDER); |
| tClassName.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
| dbc.bindValue(textProp.observe(tClassName), |
| BeanProperties.value(PROPERTY_NAME, String.class).observe(clazz), |
| new UpdateValueStrategy<>().setBeforeSetValidator(new ClassnameValidator()), null); |
| |
| new Label(parent, SWT.NONE); |
| } |
| |
| { |
| final Label l = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL); |
| l.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, false, false, 3, 1)); |
| } |
| |
| final ISWTObservableValue obsPackage = WidgetProperties.text(SWT.Modify).observe(tClassPackage); |
| final ISWTObservableValue obsClass = WidgetProperties.text(SWT.Modify).observe(tClassName); |
| final ClassMultiValidator multiValidator = new ClassMultiValidator(clazz, obsPackage, obsClass); |
| dbc.addValidationStatusProvider(multiValidator); |
| |
| createFields(parent, dbc); |
| setControl(parent); |
| } |
| |
| private String parseInitialStringForPackage(String initialString2) { |
| if (initialString2 == null) { |
| return null; |
| } |
| final int ioBC = initialString2.indexOf(BUNDLECLASS); |
| final int iSecondSlash = initialString2.lastIndexOf('/'); |
| if ( |
| |
| initialString2.length() == 0 || // empty |
| ioBC == -1 || // no bundle class |
| iSecondSlash == -1 || // no package &| class name |
| initialString2.indexOf('.') == -1// no package |
| ) { |
| return null; |
| } |
| |
| final int lastDot = initialString2.lastIndexOf('.'); |
| final String packageString = initialString2.substring(iSecondSlash + 1, lastDot); |
| return packageString; |
| } |
| |
| private String parseInitialStringForClassName(String initialString) { |
| if (initialString == null) { |
| return null; |
| } |
| final int ioBC = initialString.indexOf(BUNDLECLASS); |
| final int iSecondSlash = initialString.lastIndexOf('/'); |
| if ( |
| |
| initialString.length() == 0 || // empty |
| ioBC == -1 || // no bundle class |
| iSecondSlash == -1 || // no package &| class name |
| initialString.indexOf('.') == -1// no package |
| ) { |
| return null; |
| } |
| final int lastDot = initialString.lastIndexOf('.'); |
| if (lastDot != -1) { |
| return initialString.substring(lastDot + 1); |
| } |
| return null; |
| } |
| |
| private IPackageFragmentRoot choosePackageRoot() { |
| final IJavaElement initElement = clazz.getFragmentRoot(); |
| Class<?>[] acceptedClasses = new Class[] { IPackageFragmentRoot.class, IJavaProject.class }; |
| final TypedElementSelectionValidator validator = new TypedElementSelectionValidator(acceptedClasses, false) { |
| @Override |
| public boolean isSelectedValid(Object element) { |
| try { |
| if (element instanceof IJavaProject) { |
| final IJavaProject jproject = (IJavaProject) element; |
| final IPath path = jproject.getProject().getFullPath(); |
| return jproject.findPackageFragmentRoot(path) != null; |
| } else if (element instanceof IPackageFragmentRoot) { |
| return ((IPackageFragmentRoot) element).getKind() == IPackageFragmentRoot.K_SOURCE; |
| } |
| return true; |
| } catch (final JavaModelException e) { |
| JavaPlugin.log(e.getStatus()); // just log, no UI in validation |
| } |
| return false; |
| } |
| }; |
| |
| acceptedClasses = new Class[] { IJavaModel.class, IPackageFragmentRoot.class, IJavaProject.class }; |
| final ViewerFilter filter = new TypedViewerFilter(acceptedClasses) { |
| @Override |
| public boolean select(Viewer viewer, Object parent, Object element) { |
| if (element instanceof IPackageFragmentRoot) { |
| try { |
| return ((IPackageFragmentRoot) element).getKind() == IPackageFragmentRoot.K_SOURCE; |
| } catch (final JavaModelException e) { |
| JavaPlugin.log(e.getStatus()); // just log, no UI in validation |
| return false; |
| } |
| } |
| return super.select(viewer, parent, element); |
| } |
| }; |
| |
| final StandardJavaElementContentProvider provider = new StandardJavaElementContentProvider(); |
| final ILabelProvider labelProvider = new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_DEFAULT); |
| final ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(getShell(), labelProvider, provider); |
| dialog.setValidator(validator); |
| dialog.setComparator(new JavaElementComparator()); |
| dialog.setTitle(NewWizardMessages.NewContainerWizardPage_ChooseSourceContainerDialog_title); |
| dialog.setMessage(NewWizardMessages.NewContainerWizardPage_ChooseSourceContainerDialog_description); |
| dialog.addFilter(filter); |
| dialog.setInput(JavaCore.create(fWorkspaceRoot)); |
| dialog.setInitialSelection(initElement); |
| dialog.setHelpAvailable(false); |
| |
| if (dialog.open() == Window.OK) { |
| final Object element = dialog.getFirstResult(); |
| if (element instanceof IJavaProject) { |
| final IJavaProject jproject = (IJavaProject) element; |
| return jproject.getPackageFragmentRoot(jproject.getProject()); |
| } else if (element instanceof IPackageFragmentRoot) { |
| return (IPackageFragmentRoot) element; |
| } |
| return null; |
| } |
| return null; |
| } |
| |
| private IPackageFragment choosePackage() { |
| IJavaElement[] packages = null; |
| try { |
| if (froot != null && froot.exists()) { |
| packages = froot.getChildren(); |
| } |
| } catch (final JavaModelException e) { |
| e.printStackTrace(); |
| } |
| if (packages == null) { |
| packages = new IJavaElement[0]; |
| } |
| |
| final ElementListSelectionDialog dialog = new ElementListSelectionDialog(getShell(), |
| new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_DEFAULT)); |
| dialog.setIgnoreCase(false); |
| dialog.setTitle(Messages.AbstractNewClassPage_ChoosePackage); |
| dialog.setMessage(Messages.AbstractNewClassPage_ChooseAPackage); |
| dialog.setEmptyListMessage(Messages.AbstractNewClassPage_NeedToSelectAPackage); |
| dialog.setElements(packages); |
| dialog.setHelpAvailable(false); |
| final IPackageFragment pack = clazz.getPackageFragment(); |
| if (pack != null) { |
| dialog.setInitialSelections(new Object[] { pack }); |
| } |
| |
| if (dialog.open() == Window.OK) { |
| return (IPackageFragment) dialog.getFirstResult(); |
| } |
| return null; |
| } |
| |
| protected abstract void createFields(Composite parent, DataBindingContext dbc); |
| |
| protected abstract JavaClass createInstance(); |
| |
| public JavaClass getClazz() { |
| return clazz; |
| } |
| |
| /** |
| * Validate the specified class does not already exists |
| */ |
| static class ClassMultiValidator extends MultiValidator { |
| |
| private final JavaClass javaClass; |
| private final IObservableValue<String> observedPackage; |
| private final IObservableValue<String> observedClass; |
| |
| public ClassMultiValidator(JavaClass javaClass, final IObservableValue<String> observedPackage, |
| final IObservableValue<String> observedClass) { |
| this.javaClass = javaClass; |
| this.observedPackage = observedPackage; |
| this.observedClass = observedClass; |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @see org.eclipse.core.databinding.validation.MultiValidator#validate() |
| */ |
| @Override |
| protected IStatus validate() { |
| final String classPackage = observedPackage.getValue(); |
| final String className = observedClass.getValue(); |
| |
| final IPackageFragment packageFragment = javaClass.getFragmentRoot().getPackageFragment(classPackage); |
| |
| if (JavaClass.exists(javaClass.getFragmentRoot(), packageFragment, className)) { |
| return new Status(IStatus.ERROR, ToolsPlugin.PLUGIN_ID, Messages.AbstractNewClassPage_ClassExists); |
| } |
| |
| return ValidationStatus.ok(); |
| } |
| |
| } |
| |
| static class ClassnameValidator implements IValidator<Object> { |
| |
| @Override |
| public IStatus validate(Object value) { |
| final String name = value.toString(); |
| if (name.length() == 0) { |
| return new Status(IStatus.ERROR, ToolsPlugin.PLUGIN_ID, Messages.AbstractNewClassPage_NameNotEmpty); |
| } |
| if (name.indexOf('.') != -1 || name.trim().indexOf(' ') != -1) { |
| return new Status(IStatus.ERROR, ToolsPlugin.PLUGIN_ID, |
| Messages.AbstractNewClassPage_NameMustBeQualified); |
| } |
| |
| return JavaConventions.validateJavaTypeName(name, JavaCore.VERSION_1_3, JavaCore.VERSION_1_3); |
| } |
| } |
| |
| static class PFRootValidator implements IValidator<Object> { |
| |
| @Override |
| public IStatus validate(Object value) { |
| final String name = value.toString(); |
| if (name.length() == 0) { |
| return new Status(IStatus.ERROR, ToolsPlugin.PLUGIN_ID, |
| Messages.AbstractNewClassPage_SourceFolderNotEmpty); |
| } |
| |
| return new Status(IStatus.OK, ToolsPlugin.PLUGIN_ID, ""); //$NON-NLS-1$ |
| } |
| } |
| |
| static class PackageFragmentRootToStringConverter extends Converter<Object, Object> { |
| |
| public PackageFragmentRootToStringConverter() { |
| super(IPackageFragmentRoot.class, String.class); |
| } |
| |
| @Override |
| public Object convert(Object fromObject) { |
| final IPackageFragmentRoot f = (IPackageFragmentRoot) fromObject; |
| if (f == null) { |
| return ""; //$NON-NLS-1$ |
| } |
| return f.getPath().makeRelative().toString(); |
| } |
| } |
| |
| static class PackageFragmentToStringConverter extends Converter<Object, Object> { |
| |
| public PackageFragmentToStringConverter() { |
| super(IPackageFragment.class, String.class); |
| } |
| |
| @Override |
| public Object convert(Object fromObject) { |
| if (fromObject == null) { |
| return ""; //$NON-NLS-1$ |
| } |
| final IPackageFragment f = (IPackageFragment) fromObject; |
| return f.getElementName(); |
| } |
| } |
| |
| static class StringToPackageFragmentConverter extends Converter<Object, Object> { |
| |
| private final JavaClass clazz; |
| |
| public StringToPackageFragmentConverter(JavaClass clazz) { |
| super(String.class, IPackageFragment.class); |
| this.clazz = clazz; |
| } |
| |
| @Override |
| public Object convert(Object fromObject) { |
| if (clazz.getFragmentRoot() == null) { |
| return null; |
| } |
| if (fromObject == null) { |
| return clazz.getFragmentRoot().getPackageFragment(""); //$NON-NLS-1$ |
| } |
| |
| return clazz.getFragmentRoot().getPackageFragment((String) fromObject); |
| |
| } |
| } |
| } |