KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > wizards > NewSourceFolderWizardPage


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.ui.wizards;
12
13 import java.net.URI JavaDoc;
14 import java.util.ArrayList JavaDoc;
15 import java.util.HashSet JavaDoc;
16 import java.util.List JavaDoc;
17 import java.util.Set JavaDoc;
18
19 import org.eclipse.core.filesystem.EFS;
20 import org.eclipse.core.filesystem.IFileStore;
21
22 import org.eclipse.core.runtime.CoreException;
23 import org.eclipse.core.runtime.IPath;
24 import org.eclipse.core.runtime.IProgressMonitor;
25 import org.eclipse.core.runtime.IStatus;
26 import org.eclipse.core.runtime.NullProgressMonitor;
27 import org.eclipse.core.runtime.Path;
28 import org.eclipse.core.runtime.SubProgressMonitor;
29
30 import org.eclipse.core.resources.IFolder;
31 import org.eclipse.core.resources.IProject;
32 import org.eclipse.core.resources.IResource;
33 import org.eclipse.core.resources.IWorkspaceRoot;
34 import org.eclipse.core.resources.ResourcesPlugin;
35
36 import org.eclipse.swt.SWT;
37 import org.eclipse.swt.layout.GridLayout;
38 import org.eclipse.swt.widgets.Composite;
39
40 import org.eclipse.jface.dialogs.Dialog;
41 import org.eclipse.jface.viewers.ILabelProvider;
42 import org.eclipse.jface.viewers.IStructuredSelection;
43 import org.eclipse.jface.viewers.ITreeContentProvider;
44 import org.eclipse.jface.viewers.ViewerFilter;
45 import org.eclipse.jface.window.Window;
46
47 import org.eclipse.ui.PlatformUI;
48 import org.eclipse.ui.dialogs.ElementListSelectionDialog;
49 import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
50 import org.eclipse.ui.dialogs.ISelectionStatusValidator;
51 import org.eclipse.ui.model.WorkbenchContentProvider;
52 import org.eclipse.ui.model.WorkbenchLabelProvider;
53
54 import org.eclipse.ui.views.navigator.ResourceComparator;
55
56 import org.eclipse.jdt.core.IClasspathEntry;
57 import org.eclipse.jdt.core.IJavaElement;
58 import org.eclipse.jdt.core.IJavaModelStatus;
59 import org.eclipse.jdt.core.IJavaProject;
60 import org.eclipse.jdt.core.IPackageFragmentRoot;
61 import org.eclipse.jdt.core.JavaConventions;
62 import org.eclipse.jdt.core.JavaCore;
63 import org.eclipse.jdt.core.JavaModelException;
64
65 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
66 import org.eclipse.jdt.internal.corext.util.Messages;
67
68 import org.eclipse.jdt.ui.JavaElementLabelProvider;
69 import org.eclipse.jdt.ui.PreferenceConstants;
70 import org.eclipse.jdt.ui.wizards.NewElementWizardPage;
71
72 import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
73 import org.eclipse.jdt.internal.ui.JavaPlugin;
74 import org.eclipse.jdt.internal.ui.dialogs.StatusInfo;
75 import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;
76 import org.eclipse.jdt.internal.ui.util.CoreUtility;
77 import org.eclipse.jdt.internal.ui.wizards.buildpaths.BuildPathsBlock;
78 import org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField;
79 import org.eclipse.jdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
80 import org.eclipse.jdt.internal.ui.wizards.dialogfields.IStringButtonAdapter;
81 import org.eclipse.jdt.internal.ui.wizards.dialogfields.LayoutUtil;
82 import org.eclipse.jdt.internal.ui.wizards.dialogfields.SelectionButtonDialogField;
83 import org.eclipse.jdt.internal.ui.wizards.dialogfields.StringButtonDialogField;
84
85
86 public class NewSourceFolderWizardPage extends NewElementWizardPage {
87         
88     private static final String JavaDoc PAGE_NAME= "NewSourceFolderWizardPage"; //$NON-NLS-1$
89

90     private StringButtonDialogField fProjectField;
91     private StatusInfo fProjectStatus;
92     
93     private StringButtonDialogField fRootDialogField;
94     private StatusInfo fRootStatus;
95     
96     private SelectionButtonDialogField fExcludeInOthersFields;
97     
98     private IWorkspaceRoot fWorkspaceRoot;
99     
100     private IJavaProject fCurrJProject;
101     private IClasspathEntry[] fEntries;
102     private IPath fOutputLocation;
103     
104     private IClasspathEntry[] fNewEntries;
105     private IPath fNewOutputLocation;
106     
107     private boolean fIsProjectAsSourceFolder;
108     
109     private IPackageFragmentRoot fCreatedRoot;
110     
111     public NewSourceFolderWizardPage() {
112         super(PAGE_NAME);
113         
114         setTitle(NewWizardMessages.NewSourceFolderWizardPage_title);
115         setDescription(NewWizardMessages.NewSourceFolderWizardPage_description);
116         
117         fWorkspaceRoot= ResourcesPlugin.getWorkspace().getRoot();
118         
119         RootFieldAdapter adapter= new RootFieldAdapter();
120         
121         fProjectField= new StringButtonDialogField(adapter);
122         fProjectField.setDialogFieldListener(adapter);
123         fProjectField.setLabelText(NewWizardMessages.NewSourceFolderWizardPage_project_label);
124         fProjectField.setButtonLabel(NewWizardMessages.NewSourceFolderWizardPage_project_button);
125         
126         fRootDialogField= new StringButtonDialogField(adapter);
127         fRootDialogField.setDialogFieldListener(adapter);
128         fRootDialogField.setLabelText(NewWizardMessages.NewSourceFolderWizardPage_root_label);
129         fRootDialogField.setButtonLabel(NewWizardMessages.NewSourceFolderWizardPage_root_button);
130         
131         fExcludeInOthersFields= new SelectionButtonDialogField(SWT.CHECK);
132         fExcludeInOthersFields.setDialogFieldListener(adapter);
133         fExcludeInOthersFields.setLabelText(NewWizardMessages.NewSourceFolderWizardPage_exclude_label);
134         
135         fExcludeInOthersFields.setEnabled(JavaCore.ENABLED.equals(JavaCore.getOption(JavaCore.CORE_ENABLE_CLASSPATH_EXCLUSION_PATTERNS)));
136         
137         fRootStatus= new StatusInfo();
138         fProjectStatus= new StatusInfo();
139     }
140             
141     // -------- Initialization ---------
142

143     public void init(IStructuredSelection selection) {
144         String JavaDoc projPath= getProjectPath(selection);
145         if (projPath != null) {
146             fProjectField.setText(projPath);
147         }
148         fRootDialogField.setText(""); //$NON-NLS-1$
149
}
150
151     private String JavaDoc getProjectPath(IStructuredSelection selection) {
152         Object JavaDoc selectedElement= null;
153         if (selection == null || selection.isEmpty()) {
154             selectedElement= EditorUtility.getActiveEditorJavaInput();
155         } else if (selection.size() == 1) {
156             selectedElement= selection.getFirstElement();
157         }
158         
159         if (selectedElement instanceof IResource) {
160             IProject proj= ((IResource)selectedElement).getProject();
161             if (proj != null) {
162                 return proj.getFullPath().makeRelative().toString();
163             }
164         } else if (selectedElement instanceof IJavaElement) {
165             IJavaProject jproject= ((IJavaElement)selectedElement).getJavaProject();
166             if (jproject != null) {
167                 return jproject.getProject().getFullPath().makeRelative().toString();
168             }
169         }
170
171         return null;
172     }
173
174     // -------- UI Creation ---------
175

176     /*
177      * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
178      */

179     public void createControl(Composite parent) {
180         initializeDialogUnits(parent);
181         
182         Composite composite= new Composite(parent, SWT.NONE);
183             
184         GridLayout layout= new GridLayout();
185         layout.numColumns= 3;
186         composite.setLayout(layout);
187                 
188         fProjectField.doFillIntoGrid(composite, 3);
189         fRootDialogField.doFillIntoGrid(composite, 3);
190         fExcludeInOthersFields.doFillIntoGrid(composite, 3);
191         
192         int maxFieldWidth= convertWidthInCharsToPixels(40);
193         LayoutUtil.setWidthHint(fProjectField.getTextControl(null), maxFieldWidth);
194         LayoutUtil.setHorizontalGrabbing(fProjectField.getTextControl(null));
195         LayoutUtil.setWidthHint(fRootDialogField.getTextControl(null), maxFieldWidth);
196             
197         setControl(composite);
198         Dialog.applyDialogFont(composite);
199         PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, IJavaHelpContextIds.NEW_PACKAGEROOT_WIZARD_PAGE);
200     }
201     
202     /*
203      * @see org.eclipse.jface.dialogs.IDialogPage#setVisible(boolean)
204      */

205     public void setVisible(boolean visible) {
206         super.setVisible(visible);
207         if (visible) {
208             fRootDialogField.setFocus();
209         }
210     }
211         
212     // -------- ContainerFieldAdapter --------
213

214     private class RootFieldAdapter implements IStringButtonAdapter, IDialogFieldListener {
215
216         // -------- IStringButtonAdapter
217
public void changeControlPressed(DialogField field) {
218             packRootChangeControlPressed(field);
219         }
220         
221         // -------- IDialogFieldListener
222
public void dialogFieldChanged(DialogField field) {
223             packRootDialogFieldChanged(field);
224         }
225     }
226     protected void packRootChangeControlPressed(DialogField field) {
227         if (field == fRootDialogField) {
228             IPath initialPath= new Path(fRootDialogField.getText());
229             String JavaDoc title= NewWizardMessages.NewSourceFolderWizardPage_ChooseExistingRootDialog_title;
230             String JavaDoc message= NewWizardMessages.NewSourceFolderWizardPage_ChooseExistingRootDialog_description;
231             IFolder folder= chooseFolder(title, message, initialPath);
232             if (folder != null) {
233                 IPath path= folder.getFullPath().removeFirstSegments(1);
234                 fRootDialogField.setText(path.toString());
235             }
236         } else if (field == fProjectField) {
237             IJavaProject jproject= chooseProject();
238             if (jproject != null) {
239                 IPath path= jproject.getProject().getFullPath().makeRelative();
240                 fProjectField.setText(path.toString());
241             }
242         }
243     }
244     
245     protected void packRootDialogFieldChanged(DialogField field) {
246         if (field == fRootDialogField) {
247             updateRootStatus();
248         } else if (field == fProjectField) {
249             updateProjectStatus();
250             updateRootStatus();
251         } else if (field == fExcludeInOthersFields) {
252             updateRootStatus();
253         }
254         updateStatus(new IStatus[] { fProjectStatus, fRootStatus });
255     }
256     
257     
258     private void updateProjectStatus() {
259         fCurrJProject= null;
260         fIsProjectAsSourceFolder= false;
261         
262         String JavaDoc str= fProjectField.getText();
263         if (str.length() == 0) {
264             fProjectStatus.setError(NewWizardMessages.NewSourceFolderWizardPage_error_EnterProjectName);
265             return;
266         }
267         IPath path= new Path(str);
268         if (path.segmentCount() != 1) {
269             fProjectStatus.setError(NewWizardMessages.NewSourceFolderWizardPage_error_InvalidProjectPath);
270             return;
271         }
272         IProject project= fWorkspaceRoot.getProject(path.toString());
273         if (!project.exists()) {
274             fProjectStatus.setError(NewWizardMessages.NewSourceFolderWizardPage_error_ProjectNotExists);
275             return;
276         }
277         if (!project.isOpen()) {
278             fProjectStatus.setError(NewWizardMessages.NewSourceFolderWizardPage_error_ProjectNotOpen);
279             return;
280         }
281         try {
282             if (project.hasNature(JavaCore.NATURE_ID)) {
283                 fCurrJProject= JavaCore.create(project);
284                 fEntries= fCurrJProject.getRawClasspath();
285                 fOutputLocation= fCurrJProject.getOutputLocation();
286                 fProjectStatus.setOK();
287                 return;
288             }
289         } catch (CoreException e) {
290             JavaPlugin.log(e);
291             fCurrJProject= null;
292         }
293         fProjectStatus.setError(NewWizardMessages.NewSourceFolderWizardPage_error_NotAJavaProject);
294     }
295
296     private void updateRootStatus() {
297         fRootDialogField.enableButton(fCurrJProject != null);
298         fIsProjectAsSourceFolder= false;
299         if (fCurrJProject == null) {
300             return;
301         }
302         fRootStatus.setOK();
303         
304         IPath projPath= fCurrJProject.getProject().getFullPath();
305         String JavaDoc str= fRootDialogField.getText();
306         if (str.length() == 0) {
307             fRootStatus.setError(Messages.format(NewWizardMessages.NewSourceFolderWizardPage_error_EnterRootName, fCurrJProject.getProject().getFullPath().toString()));
308         } else {
309             IPath path= projPath.append(str);
310             IStatus validate= fWorkspaceRoot.getWorkspace().validatePath(path.toString(), IResource.FOLDER);
311             if (validate.matches(IStatus.ERROR)) {
312                 fRootStatus.setError(Messages.format(NewWizardMessages.NewSourceFolderWizardPage_error_InvalidRootName, validate.getMessage()));
313             } else {
314                 IResource res= fWorkspaceRoot.findMember(path);
315                 if (res != null) {
316                     if (res.getType() != IResource.FOLDER) {
317                         fRootStatus.setError(NewWizardMessages.NewSourceFolderWizardPage_error_NotAFolder);
318                         return;
319                     }
320                 } else {
321                     URI JavaDoc projLocation= fCurrJProject.getProject().getLocationURI();
322                     if (projLocation != null) {
323                         try {
324                             IFileStore store= EFS.getStore(projLocation).getChild(str);
325                             if (store.fetchInfo().exists()) {
326                                 fRootStatus.setError(NewWizardMessages.NewSourceFolderWizardPage_error_AlreadyExistingDifferentCase);
327                                 return;
328                             }
329                         } catch (CoreException e) {
330                             // we couldn't create the file store. Ignore the exception
331
// since we can't check if the file exist. Pretend that it
332
// doesn't.
333
}
334                     }
335                 }
336                 ArrayList JavaDoc newEntries= new ArrayList JavaDoc(fEntries.length + 1);
337                 int projectEntryIndex= -1;
338                 
339                 for (int i= 0; i < fEntries.length; i++) {
340                     IClasspathEntry curr= fEntries[i];
341                     if (curr.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
342                         if (path.equals(curr.getPath())) {
343                             fRootStatus.setError(NewWizardMessages.NewSourceFolderWizardPage_error_AlreadyExisting);
344                             return;
345                         }
346                         if (projPath.equals(curr.getPath())) {
347                             projectEntryIndex= i;
348                         }
349                     }
350                     newEntries.add(curr);
351                 }
352                 
353                 IClasspathEntry newEntry= JavaCore.newSourceEntry(path);
354                 
355                 Set JavaDoc modified= new HashSet JavaDoc();
356                 if (fExcludeInOthersFields.isSelected()) {
357                     addExclusionPatterns(newEntry, newEntries, modified);
358                     IClasspathEntry entry= JavaCore.newSourceEntry(path);
359                     insertAtEndOfCategory(entry, newEntries);
360                 } else {
361                     if (projectEntryIndex != -1) {
362                         fIsProjectAsSourceFolder= true;
363                         newEntries.set(projectEntryIndex, newEntry);
364                     } else {
365                         IClasspathEntry entry= JavaCore.newSourceEntry(path);
366                         insertAtEndOfCategory(entry, newEntries);
367                     }
368                 }
369                     
370                 fNewEntries= (IClasspathEntry[]) newEntries.toArray(new IClasspathEntry[newEntries.size()]);
371                 fNewOutputLocation= fOutputLocation;
372
373                 IJavaModelStatus status= JavaConventions.validateClasspath(fCurrJProject, fNewEntries, fNewOutputLocation);
374                 if (!status.isOK()) {
375                     if (fOutputLocation.equals(projPath)) {
376                         fNewOutputLocation= projPath.append(PreferenceConstants.getPreferenceStore().getString(PreferenceConstants.SRCBIN_BINNAME));
377                         IStatus status2= JavaConventions.validateClasspath(fCurrJProject, fNewEntries, fNewOutputLocation);
378                         if (status2.isOK()) {
379                             if (fIsProjectAsSourceFolder) {
380                                 fRootStatus.setInfo(Messages.format(NewWizardMessages.NewSourceFolderWizardPage_warning_ReplaceSFandOL, fNewOutputLocation.makeRelative().toString()));
381                             } else {
382                                 fRootStatus.setInfo(Messages.format(NewWizardMessages.NewSourceFolderWizardPage_warning_ReplaceOL, fNewOutputLocation.makeRelative().toString()));
383                             }
384                             return;
385                         }
386                     }
387                     fRootStatus.setError(status.getMessage());
388                     return;
389                 } else if (fIsProjectAsSourceFolder) {
390                     fRootStatus.setInfo(NewWizardMessages.NewSourceFolderWizardPage_warning_ReplaceSF);
391                     return;
392                 }
393                 if (!modified.isEmpty()) {
394                     fRootStatus.setInfo(Messages.format(NewWizardMessages.NewSourceFolderWizardPage_warning_AddedExclusions, String.valueOf(modified.size())));
395                     return;
396                 }
397             }
398         }
399     }
400     
401     private void insertAtEndOfCategory(IClasspathEntry entry, List JavaDoc entries) {
402         int length= entries.size();
403         IClasspathEntry[] elements= (IClasspathEntry[])entries.toArray(new IClasspathEntry[length]);
404         int i= 0;
405         while (i < length && elements[i].getEntryKind() != entry.getEntryKind()) {
406             i++;
407         }
408         if (i < length) {
409             i++;
410             while (i < length && elements[i].getEntryKind() == entry.getEntryKind()) {
411                 i++;
412             }
413             entries.add(i, entry);
414             return;
415         }
416         
417         switch (entry.getEntryKind()) {
418         case IClasspathEntry.CPE_SOURCE:
419             entries.add(0, entry);
420             break;
421         case IClasspathEntry.CPE_CONTAINER:
422         case IClasspathEntry.CPE_LIBRARY:
423         case IClasspathEntry.CPE_PROJECT:
424         case IClasspathEntry.CPE_VARIABLE:
425         default:
426             entries.add(entry);
427             break;
428         }
429     }
430     
431     private void addExclusionPatterns(IClasspathEntry newEntry, List JavaDoc existing, Set JavaDoc modifiedEntries) {
432         IPath entryPath= newEntry.getPath();
433         for (int i= 0; i < existing.size(); i++) {
434             IClasspathEntry curr= (IClasspathEntry) existing.get(i);
435             IPath currPath= curr.getPath();
436             if (curr.getEntryKind() == IClasspathEntry.CPE_SOURCE && currPath.isPrefixOf(entryPath)) {
437                 IPath[] exclusionFilters= curr.getExclusionPatterns();
438                 if (!JavaModelUtil.isExcludedPath(entryPath, exclusionFilters)) {
439                     IPath pathToExclude= entryPath.removeFirstSegments(currPath.segmentCount()).addTrailingSeparator();
440                     IPath[] newExclusionFilters= new IPath[exclusionFilters.length + 1];
441                     System.arraycopy(exclusionFilters, 0, newExclusionFilters, 0, exclusionFilters.length);
442                     newExclusionFilters[exclusionFilters.length]= pathToExclude;
443                     
444                     IClasspathEntry updated= JavaCore.newSourceEntry(currPath, newExclusionFilters, curr.getOutputLocation());
445                     existing.set(i, updated);
446                     modifiedEntries.add(updated);
447                 }
448             }
449         }
450     }
451     
452     // ---- creation ----------------
453

454     public IPackageFragmentRoot getNewPackageFragmentRoot() {
455         return fCreatedRoot;
456     }
457     
458     public IResource getCorrespondingResource() {
459         return fCurrJProject.getProject().getFolder(fRootDialogField.getText());
460     }
461     
462     public void createPackageFragmentRoot(IProgressMonitor monitor) throws CoreException, InterruptedException JavaDoc {
463         if (monitor == null) {
464             monitor= new NullProgressMonitor();
465         }
466         monitor.beginTask(NewWizardMessages.NewSourceFolderWizardPage_operation, 3);
467         try {
468             IPath projPath= fCurrJProject.getProject().getFullPath();
469             if (fOutputLocation.equals(projPath) && !fNewOutputLocation.equals(projPath)) {
470                 if (BuildPathsBlock.hasClassfiles(fCurrJProject.getProject())) {
471                     if (BuildPathsBlock.getRemoveOldBinariesQuery(getShell()).doQuery(false, projPath)) {
472                         BuildPathsBlock.removeOldClassfiles(fCurrJProject.getProject());
473                     }
474                 }
475             }
476             
477             String JavaDoc relPath= fRootDialogField.getText();
478                 
479             IFolder folder= fCurrJProject.getProject().getFolder(relPath);
480             if (!folder.exists()) {
481                 CoreUtility.createFolder(folder, true, true, new SubProgressMonitor(monitor, 1));
482             }
483             if (monitor.isCanceled()) {
484                 throw new InterruptedException JavaDoc();
485             }
486             
487             fCurrJProject.setRawClasspath(fNewEntries, fNewOutputLocation, new SubProgressMonitor(monitor, 2));
488     
489             fCreatedRoot= fCurrJProject.getPackageFragmentRoot(folder);
490         } finally {
491             monitor.done();
492         }
493     }
494         
495     // ------------- choose dialogs
496

497     private IFolder chooseFolder(String JavaDoc title, String JavaDoc message, IPath initialPath) {
498         Class JavaDoc[] acceptedClasses= new Class JavaDoc[] { IFolder.class };
499         ISelectionStatusValidator validator= new TypedElementSelectionValidator(acceptedClasses, false);
500         ViewerFilter filter= new TypedViewerFilter(acceptedClasses, null);
501         
502         ILabelProvider lp= new WorkbenchLabelProvider();
503         ITreeContentProvider cp= new WorkbenchContentProvider();
504
505         IProject currProject= fCurrJProject.getProject();
506
507         ElementTreeSelectionDialog dialog= new ElementTreeSelectionDialog(getShell(), lp, cp);
508         dialog.setValidator(validator);
509         dialog.setTitle(title);
510         dialog.setMessage(message);
511         dialog.addFilter(filter);
512         dialog.setInput(currProject);
513         dialog.setComparator(new ResourceComparator(ResourceComparator.NAME));
514         IResource res= currProject.findMember(initialPath);
515         if (res != null) {
516             dialog.setInitialSelection(res);
517         }
518
519         if (dialog.open() == Window.OK) {
520             return (IFolder) dialog.getFirstResult();
521         }
522         return null;
523     }
524     
525     private IJavaProject chooseProject() {
526         IJavaProject[] projects;
527         try {
528             projects= JavaCore.create(fWorkspaceRoot).getJavaProjects();
529         } catch (JavaModelException e) {
530             JavaPlugin.log(e);
531             projects= new IJavaProject[0];
532         }
533         
534         ILabelProvider labelProvider= new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_DEFAULT);
535         ElementListSelectionDialog dialog= new ElementListSelectionDialog(getShell(), labelProvider);
536         dialog.setTitle(NewWizardMessages.NewSourceFolderWizardPage_ChooseProjectDialog_title);
537         dialog.setMessage(NewWizardMessages.NewSourceFolderWizardPage_ChooseProjectDialog_description);
538         dialog.setElements(projects);
539         dialog.setInitialSelections(new Object JavaDoc[] { fCurrJProject });
540         dialog.setHelpAvailable(false);
541         if (dialog.open() == Window.OK) {
542             return (IJavaProject) dialog.getFirstResult();
543         }
544         return null;
545     }
546                 
547 }
548
Popular Tags