Author: scabanovich
Date: 2008-05-29 10:29:48 -0400 (Thu, 29 May 2008)
New Revision: 8438
Added:
trunk/seam/plugins/org.jboss.tools.seam.pages.xml/src/org/jboss/tools/seam/pages/xml/model/handlers/AddViewSupport.java
Modified:
trunk/seam/plugins/org.jboss.tools.seam.pages.xml/plugin.xml
trunk/seam/plugins/org.jboss.tools.seam.pages.xml/resources/meta/seam-pages-wizards.meta
trunk/seam/plugins/org.jboss.tools.seam.pages.xml/resources/meta/seam-pages.meta
trunk/seam/plugins/org.jboss.tools.seam.pages.xml/src/org/jboss/tools/seam/pages/xml/SeamPagesXMLMessages.java
trunk/seam/plugins/org.jboss.tools.seam.pages.xml/src/org/jboss/tools/seam/pages/xml/messages.properties
trunk/seam/plugins/org.jboss.tools.seam.pages.xml/src/org/jboss/tools/seam/pages/xml/model/helpers/SeamPagesProcessHelper.java
Log:
JBIDE-1189
Modified: trunk/seam/plugins/org.jboss.tools.seam.pages.xml/plugin.xml
===================================================================
--- trunk/seam/plugins/org.jboss.tools.seam.pages.xml/plugin.xml 2008-05-29 14:29:29 UTC
(rev 8437)
+++ trunk/seam/plugins/org.jboss.tools.seam.pages.xml/plugin.xml 2008-05-29 14:29:48 UTC
(rev 8438)
@@ -66,6 +66,9 @@
class="org.jboss.tools.seam.pages.xml.model.handlers.OpenPageHandler"/>
<xclass
id="org.jboss.tools.seam.pages.xml.model.handlers.SelectOnDiagramHandler"
class="org.jboss.tools.seam.pages.xml.model.handlers.SelectOnDiagramHandler"/>
+
+ <xclass id="org.jboss.tools.seam.pages.xml.model.handlers.AddViewSupport"
+ class="org.jboss.tools.seam.pages.xml.model.handlers.AddViewSupport"/>
</extension>
<extension point="org.eclipse.wst.xml.core.catalogContributions">
Modified:
trunk/seam/plugins/org.jboss.tools.seam.pages.xml/resources/meta/seam-pages-wizards.meta
===================================================================
---
trunk/seam/plugins/org.jboss.tools.seam.pages.xml/resources/meta/seam-pages-wizards.meta 2008-05-29
14:29:29 UTC (rev 8437)
+++
trunk/seam/plugins/org.jboss.tools.seam.pages.xml/resources/meta/seam-pages-wizards.meta 2008-05-29
14:29:48 UTC (rev 8438)
@@ -89,4 +89,30 @@
<XActionItem kind="list"/>
<XDependencies/>
</XModelEntity>
+ <XModelEntity name="SeamPagesAddViewWizard">
+ <XChildrenEntities/>
+ <XEntityRenderer/>
+ <XModelAttributes>
+ <XModelAttribute name="view id">
+ <Constraint loader="Tree">
+ <value name="JSFPageTree"/>
+ <value name="extensions=jsp,html,htm,xhtml"/>
+ </Constraint>
+ <Editor name="TreeChooser"/>
+ </XModelAttribute>
+ <XModelAttribute default="true" name="create file">
+ <Constraint loader="List">
+ <value name="true"/>
+ <value name="false"/>
+ </Constraint>
+ <Editor name="CheckBox"/>
+ </XModelAttribute>
+ <XModelAttribute name="template">
+ <Constraint loader="ListString"/>
+ <Editor name="ListString"/>
+ </XModelAttribute>
+ </XModelAttributes>
+ <XActionItem kind="list"/>
+ <XDependencies/>
+ </XModelEntity>
</XModelEntityGroup>
Modified:
trunk/seam/plugins/org.jboss.tools.seam.pages.xml/resources/meta/seam-pages.meta
===================================================================
---
trunk/seam/plugins/org.jboss.tools.seam.pages.xml/resources/meta/seam-pages.meta 2008-05-29
14:29:29 UTC (rev 8437)
+++
trunk/seam/plugins/org.jboss.tools.seam.pages.xml/resources/meta/seam-pages.meta 2008-05-29
14:29:48 UTC (rev 8438)
@@ -2809,7 +2809,17 @@
</XModelAttribute>
</XModelAttributes>
<XActionItem kind="list">
- <XActionItem ICON="action.empty" displayName="New"
kind="list" name="CreateActions"/>
+ <XActionItem ICON="action.empty" displayName="New"
kind="list" name="CreateActions">
+ <XActionItem HandlerClassName="%SpecialWizard%"
ICON="action.empty"
+
PROPERTIES="support=org.jboss.tools.seam.pages.xml.model.handlers.AddViewSupport"
+ displayName="New Page..." kind="action"
name="AddPage">
+ <EntityData EntityName="SeamPagesAddViewWizard">
+ <AttributeData AttributeName="view id" Mandatory="no"/>
+ <AttributeData AttributeName="create file"
Mandatory="no"/>
+ <AttributeData AttributeName="template" Mandatory="no"/>
+ </EntityData>
+ </XActionItem>
+ </XActionItem>
<XActionItem HIDE="always"
HandlerClassName="org.jboss.tools.jsf.model.handlers.CreateCommentHandler"
ICON="action.empty" WizardClassName="%OneParameter%"
Modified:
trunk/seam/plugins/org.jboss.tools.seam.pages.xml/src/org/jboss/tools/seam/pages/xml/SeamPagesXMLMessages.java
===================================================================
---
trunk/seam/plugins/org.jboss.tools.seam.pages.xml/src/org/jboss/tools/seam/pages/xml/SeamPagesXMLMessages.java 2008-05-29
14:29:29 UTC (rev 8437)
+++
trunk/seam/plugins/org.jboss.tools.seam.pages.xml/src/org/jboss/tools/seam/pages/xml/SeamPagesXMLMessages.java 2008-05-29
14:29:48 UTC (rev 8438)
@@ -3,12 +3,21 @@
import java.util.MissingResourceException;
import java.util.ResourceBundle;
-public class SeamPagesXMLMessages {
+import org.eclipse.osgi.util.NLS;
+
+public class SeamPagesXMLMessages extends NLS {
private static final String BUNDLE_NAME =
"org.jboss.tools.seam.pages.xml.messages"; //$NON-NLS-1$
private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
.getBundle(BUNDLE_NAME);
+ public static String WARNING;
+ public static String ATTRIBUTE_VIEW_ID_IS_NOT_CORRECT;
+ public static String TEMPLATE_IS_NOT_SPECIFIED;
+ public static String TEMPLATE_DOES_NOT_EXIST;
+ public static String THE_VIEW_WITH_PATH_IS_ALREADY_CREATED;
+ public static String TEMPLATE_IS_NOT_FOUND;
+
private SeamPagesXMLMessages() {
}
@@ -19,4 +28,10 @@
return '!' + key + '!';
}
}
+
+ static {
+ // load message values from bundle file
+ NLS.initializeMessages(BUNDLE_NAME, SeamPagesXMLMessages.class);
+ }
+
}
Modified:
trunk/seam/plugins/org.jboss.tools.seam.pages.xml/src/org/jboss/tools/seam/pages/xml/messages.properties
===================================================================
---
trunk/seam/plugins/org.jboss.tools.seam.pages.xml/src/org/jboss/tools/seam/pages/xml/messages.properties 2008-05-29
14:29:29 UTC (rev 8437)
+++
trunk/seam/plugins/org.jboss.tools.seam.pages.xml/src/org/jboss/tools/seam/pages/xml/messages.properties 2008-05-29
14:29:48 UTC (rev 8438)
@@ -1 +1,7 @@
SEAM_PAGES_XML_PLUGIN_NO_MESSAGE=No message
+WARNING = Warning
+ATTRIBUTE_VIEW_ID_IS_NOT_CORRECT=Attribute 'view id' is not correct
+TEMPLATE_IS_NOT_SPECIFIED = Template is not specified
+TEMPLATE_DOES_NOT_EXIST = Template does not exist.
+THE_VIEW_WITH_PATH_IS_ALREADY_CREATED = The View with 'view id' '{0}' is
already created.\n
+TEMPLATE_IS_NOT_FOUND = Template {0} is not found.
Added:
trunk/seam/plugins/org.jboss.tools.seam.pages.xml/src/org/jboss/tools/seam/pages/xml/model/handlers/AddViewSupport.java
===================================================================
---
trunk/seam/plugins/org.jboss.tools.seam.pages.xml/src/org/jboss/tools/seam/pages/xml/model/handlers/AddViewSupport.java
(rev 0)
+++
trunk/seam/plugins/org.jboss.tools.seam.pages.xml/src/org/jboss/tools/seam/pages/xml/model/handlers/AddViewSupport.java 2008-05-29
14:29:48 UTC (rev 8438)
@@ -0,0 +1,339 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc.
+ * Distributed under license by Red Hat, Inc. All rights reserved.
+ * This program is 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:
+ * Exadel, Inc. and Red Hat, Inc. - initial API and implementation
+ ******************************************************************************/
+package org.jboss.tools.seam.pages.xml.model.handlers;
+
+import java.io.File;
+import java.util.Properties;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.osgi.util.NLS;
+import org.jboss.tools.common.meta.action.impl.DefaultWizardDataValidator;
+import org.jboss.tools.common.meta.action.impl.SpecialWizardSupport;
+import org.jboss.tools.common.meta.action.impl.WizardDataValidator;
+import org.jboss.tools.common.meta.action.impl.handlers.DefaultCreateHandler;
+import org.jboss.tools.common.model.ServiceDialog;
+import org.jboss.tools.common.model.XModelException;
+import org.jboss.tools.common.model.XModelObject;
+import org.jboss.tools.common.model.filesystems.impl.FileSystemImpl;
+import org.jboss.tools.common.model.options.PreferenceModelUtilities;
+import org.jboss.tools.common.model.util.EclipseResourceUtil;
+import org.jboss.tools.common.model.util.FindObjectHelper;
+import org.jboss.tools.common.model.util.ModelFeatureFactory;
+import org.jboss.tools.common.util.FileUtil;
+import org.jboss.tools.jst.web.model.ReferenceObject;
+import org.jboss.tools.jst.web.project.helpers.AbstractWebProjectTemplate;
+import org.jboss.tools.seam.pages.xml.SeamPagesXMLMessages;
+import org.jboss.tools.seam.pages.xml.SeamPagesXMLPlugin;
+import org.jboss.tools.seam.pages.xml.model.SeamPagesConstants;
+import org.jboss.tools.seam.pages.xml.model.helpers.SeamPagesProcessHelper;
+
+public class AddViewSupport extends SpecialWizardSupport implements SeamPagesConstants {
+ public static String JSF_ADD_VIEW_PATH = ""; //preference name
+ AbstractWebProjectTemplate templates =
(AbstractWebProjectTemplate)ModelFeatureFactory.getInstance().createFeatureInstance("org.jboss.tools.jsf.web.JSFTemplate");
+ static String LAST_CREATE_FILE_PREFERENCE =
"org.jboss.tools.jsf.lastCreateFileValue";
+ XModelObject sample;
+
+ public void reset() {
+ sample = (XModelObject)getProperties().get("sample");
+ if(sample != null) {
+ setAttributeValue(0, ATTR_VIEW_ID, sample.getAttributeValue(ATTR_PATH));
+ }
+ if(templates != null) {
+ templates.updatePageTemplates();
+ String[] s = templates.getPageTemplateList();
+ setValueList(0, "template", s);
+ //take from preferences
+ setAttributeValue(0, "template", getDefaultTemplate(s));
+ }
+ //TODO combine this feature with jsf
+ String last =
SeamPagesXMLPlugin.getDefault().getPluginPreferences().getString(LAST_CREATE_FILE_PREFERENCE);
+ if(last == null || last.length() == 0) {
+ last = "true";
+ } else if(!"true".equals(last)) {
+ last = "false";
+ }
+ setAttributeValue(0, "create file", last);
+ }
+
+ static XModelObject getPreferenceObject() {
+ return PreferenceModelUtilities.getPreferenceModel().getByPath(JSF_ADD_VIEW_PATH);
+ }
+
+ public String getDefaultTemplate(String[] list) {
+ if(list.length == 0) return "";
+ XModelObject addView = getPreferenceObject();
+ String v = (addView == null) ? "" : addView.getAttributeValue("Page
Template");
+ if(v != null) for (int i = 0; i < list.length; i++) if(v.equals(list[i])) return
list[i];
+ return list[0];
+ }
+
+ public String getExtension(String template) {
+ if(template != null) {
+ int i = template.trim().lastIndexOf('.');
+ if(i > 0) {
+ return template.trim().substring(i);
+ }
+ }
+ return getExtension();
+ }
+
+ public static String getExtension() {
+ XModelObject addView = getPreferenceObject();
+ String v = (addView == null) ? "" :
addView.getAttributeValue("Extension");
+ if(v == null || v.length() == 0) return ".jsp";
+ if(!v.startsWith(".")) v = "." + v;
+ return v;
+ }
+
+ public void action(String name) throws XModelException {
+ if(FINISH.equals(name)) {
+ execute();
+ setFinished(true);
+ } else if(CANCEL.equals(name)) {
+ setFinished(true);
+ }
+ }
+
+ public String[] getActionNames(int stepId) {
+ return new String[]{FINISH, CANCEL, HELP};
+ }
+
+ protected void execute() throws XModelException {
+ boolean doNotCreateEmptyRule = false;
//"yes".equals(JSFPreference.DO_NOT_CREATE_EMPTY_RULE.getValue());
+ Properties p = extractStepData(0);
+ String path = p.getProperty(ATTR_VIEW_ID);
+ path = revalidatePath(path, getAttributeValue(0, "template"));
+
+ createFile(path);
+
+ XModelObject m = getTarget().getParent().getChildByPath(FOLDER_PAGES);
+ String pp = SeamPagesProcessHelper.toNavigationRulePathPart(path);
+ boolean isPattern = SeamPagesProcessHelper.isPattern(path);
+ boolean existsR = m.getChildByPath(path) != null; // m.getRuleCount(path) != 0;
+ boolean existsV = findView(path) != null;
+
+ boolean exists = existsR || existsV;
+ if(exists) {
+ ServiceDialog d = getTarget().getModel().getService();
+ String message = NLS.bind(SeamPagesXMLMessages.THE_VIEW_WITH_PATH_IS_ALREADY_CREATED,
path);
+ if(existsR) {
+// message +=
JSFUIMessages.YOU_WANT_TO_ADD_ADDITIONAL_NAVIGATION_RULE_WITH_SAME_FROM_VIEW_ID;
+ //Do not support
+ } else if(existsV && isPattern) {
+// message +=
JSFUIMessages.YOU_WANT_TO_CREATE_AN_ADDITIONAL_VIEW_WITH_THE_SAME_FROM_VIEW_ID;
+ //Do not support
+ } else {
+// message +=
JSFUIMessages.YOU_WANT_TO_CREATE_A_NAVIGATION_RULE_FOR_THIS_FROM_VIEW_ID;
+ //Do not support
+ }
+ int q = d.showDialog(SeamPagesXMLMessages.WARNING, message, new String[]{OK/*,
CANCEL*/}, null, ServiceDialog.WARNING);
+// if(q != 0) return;
+ return;
+ }
+
+ XModelObject created = null;
+ if(!doNotCreateEmptyRule || (exists && !isPattern) || sample != null) {
+ XModelObject rule = addPage(m, path); // m.addRule(path);
+ addCasesFromSample(rule);
+ m.setModified(true);
+ created = getTarget().getChildByPath(pp);
+ } else {
+ created =
getTarget().getModel().createModelObject(SeamPagesConstants.ENT_PROCESS_ITEM, null);
+ String ppi = pp;
+// if(exists && SeamPagesProcessHelper.isPattern(path)) {
+// int index = -1;
+// while(getTarget().getChildByPath(ppi + ":" + index) != null) index--;
+// ppi = ppi + ":" + index;
+// }
+ created.setAttributeValue(SeamPagesConstants.ATTR_NAME, ppi);
+ created.setAttributeValue(SeamPagesConstants.ATTR_PATH, path);
+ created.setAttributeValue("persistent", "true");
+ DefaultCreateHandler.addCreatedObject(getTarget(), created, getProperties());
+ }
+
+ if(!exists || isPattern) {
+ String shape = getShape();
+ if(created != null && shape != null)
created.setAttributeValue("shape", shape);
+ }
+ if(created != null) {
+ FindObjectHelper.findModelObject(created, FindObjectHelper.IN_EDITOR_ONLY);
+ }
+ }
+
+ private XModelObject addPage(XModelObject pages, String path) {
+ String childEntity = pages.getModelEntity().getChildren()[0].getName();
+ XModelObject page = pages.getModel().createModelObject(childEntity, null);
+ page.setAttributeValue(ATTR_VIEW_ID, path);
+ pages.addChild(page);
+ return page;
+ }
+
+ private XModelObject findView(String path) {
+ String pp = SeamPagesProcessHelper.toNavigationRulePathPart(path);
+ XModelObject o = getTarget().getChildByPath(pp);
+ if(o != null) return o;
+ if(!SeamPagesProcessHelper.isPattern(path)) return null;
+ XModelObject[] cs = getTarget().getChildren();
+ for (int i = 0; i < cs.length; i++) {
+ String p = cs[i].getPathPart();
+ if(pp.equals(p) || p.startsWith(pp + ":")) return cs[i];
+ }
+ return null;
+ }
+
+ private void addCasesFromSample(XModelObject rule) {
+ if(!(sample instanceof ReferenceObject)) return;
+ XModelObject rs = ((ReferenceObject)sample).getReference();
+ if(rs == null) return;
+ XModelObject[] cs = rs.getChildren();
+ for (int j = 0; j < cs.length; j++) {
+ rule.addChild(cs[j].copy());
+ }
+
+ }
+
+ private String getShape() {
+ String x = getProperties().getProperty("process.mouse.x");
+ String y = getProperties().getProperty("process.mouse.y");
+ return (x == null || y == null) ? null : x + "," + y + ",0,0";
+ }
+
+ public static String revalidatePath(String path) {
+ if(path != null) path = path.trim();
+ if(path == null || path.length() == 0) return path;
+ if(!path.startsWith("/") && !path.startsWith("*")) path =
"/" + path;
+ if(path.indexOf('*') >= 0) return path;
+ if(path.indexOf('.') < 0 && !path.endsWith("/")) {
+ path += getExtension();
+ }
+ return path;
+ }
+
+ String revalidatePath(String path, String template) {
+ if(path != null) path = path.trim();
+ if(path == null || path.length() == 0) return path;
+ if(!path.startsWith("/") && !path.startsWith("*")) path =
"/" + path;
+ if(path.indexOf('*') >= 0) return path;
+ if(path.indexOf('.') < 0 && !path.endsWith("/")) {
+ path += getExtension(template);
+ }
+ return path;
+ }
+
+ public boolean canCreateFile(String path) {
+ XModelObject fs = getTarget().getModel().getByPath("FileSystems/WEB-ROOT");
+ if(fs == null) return false;
+ path = revalidatePath(path, getAttributeValue(0, "template"));
+ if(path == null || path.length() == 0 || path.indexOf('*') >= 0) return
false;
+ return isCorrectPath(path) && !fileExists(path);
+ }
+
+ static String FORBIDDEN_INDICES = "\"\n\t*\\:<>?|";
+
+ static boolean isCorrectPath(String path) {
+ if(path == null || path.equals("/") || path.indexOf("//") >= 0)
return false;
+ if(path.endsWith("/") || path.indexOf("../") >= 0) return
false;
+ if(path.endsWith("..")) return false;
+ if(path.equals("*")) return true;
+ for (int i = 0; i < FORBIDDEN_INDICES.length(); i++) {
+ if(path.indexOf(FORBIDDEN_INDICES.charAt(i)) >= 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ boolean fileExists(String path) {
+ return getTarget().getModel().getByPath(path) != null;
+ }
+
+ void createFile(String path) throws XModelException {
+ if(!canCreateFile(path)) return;
+ String lastCreateFileValue = getAttributeValue(0, "create file");
+ SeamPagesXMLPlugin.getDefault().getPluginPreferences().setDefault(LAST_CREATE_FILE_PREFERENCE,
lastCreateFileValue);
+ if(!"true".equals(lastCreateFileValue)) return;
+ String template = getAttributeValue(0, "template");
+ if(template != null) template = template.trim();
+ File fs = null;
+ if(templates != null) {
+ fs = (File)templates.getPageTemplates().get(template);
+ if(fs == null || !fs.isFile()) throw new
XModelException(NLS.bind(SeamPagesXMLMessages.TEMPLATE_IS_NOT_FOUND, template));
+ }
+ String location =
((FileSystemImpl)getTarget().getModel().getByPath("FileSystems/WEB-ROOT")).getAbsoluteLocation();
+ location += path;
+ File ft = new File(location);
+ ft.getParentFile().mkdirs();
+ if(fs != null) FileUtil.copyFile(fs, ft);
+ getTarget().getModel().update();
+ try {
+ EclipseResourceUtil.getResource(getTarget()).getProject().refreshLocal(IProject.DEPTH_INFINITE,
null);
+ } catch (CoreException e) {
+ throw new XModelException(e);
+ }
+ }
+
+ protected DefaultWizardDataValidator viewValidator = new ViewValidator();
+
+ public WizardDataValidator getValidator(int step) {
+ viewValidator.setSupport(this, step);
+ return viewValidator;
+ }
+
+ class ViewValidator extends DefaultWizardDataValidator {
+ public void validate(Properties data) {
+ super.validate(data);
+ if(message != null) return;
+ String path = revalidatePath(data.getProperty(SeamPagesConstants.ATTR_VIEW_ID),
data.getProperty("template"));
+ if(!isCorrectPath(path)) {
+ message = SeamPagesXMLMessages.ATTRIBUTE_VIEW_ID_IS_NOT_CORRECT;
+ }
+ if(message != null) return;
+
+ String template = data.getProperty("template");
+ if(template != null && isFieldEditorEnabled(0, "template", data)) {
+ if(template.trim().length() == 0) {
+ message = SeamPagesXMLMessages.TEMPLATE_IS_NOT_SPECIFIED;
+ return;
+ }
+ if (templates != null) {
+ File templateFile = (File) templates.getPageTemplates()
+ .get(template.trim());
+ if (templateFile == null || !templateFile.isFile()) {
+ message = SeamPagesXMLMessages.TEMPLATE_DOES_NOT_EXIST;
+ }
+ }
+ }
+ if(message != null) return;
+
+ boolean doNotCreateEmptyRule = false;
//"yes".equals(JSFPreference.DO_NOT_CREATE_EMPTY_RULE.getValue());
+ String pp = SeamPagesProcessHelper.toNavigationRulePathPart(path);
+ boolean exists = getTarget().getChildByPath(pp) != null;
+ if(doNotCreateEmptyRule && exists /*&&
!SeamPagesProcessHelper.isPattern(path)*/) {
+ message = "View exists."; //JSFUIMessages.THE_VIEW_EXISTS;
+ }
+
+ }
+ }
+
+ public boolean isFieldEditorEnabled(int stepId, String name, Properties values) {
+ String path = values.getProperty(ATTR_VIEW_ID);
+ boolean c = canCreateFile(path);
+ if(name.equals("create file")) {
+ return c;
+ }
+ boolean g = c && "true".equals(values.getProperty("create
file"));
+ if(name.equals("template")) {
+ return g;
+ }
+ return true;
+ }
+
+}
Modified:
trunk/seam/plugins/org.jboss.tools.seam.pages.xml/src/org/jboss/tools/seam/pages/xml/model/helpers/SeamPagesProcessHelper.java
===================================================================
---
trunk/seam/plugins/org.jboss.tools.seam.pages.xml/src/org/jboss/tools/seam/pages/xml/model/helpers/SeamPagesProcessHelper.java 2008-05-29
14:29:29 UTC (rev 8437)
+++
trunk/seam/plugins/org.jboss.tools.seam.pages.xml/src/org/jboss/tools/seam/pages/xml/model/helpers/SeamPagesProcessHelper.java 2008-05-29
14:29:48 UTC (rev 8438)
@@ -362,4 +362,9 @@
int i = pathpart.lastIndexOf(':');
return (i < 0) ? pathpart : pathpart.substring(0, i);
}
+
+ public static boolean isPattern(String path) {
+ return path != null && (path.length() == 0 || path.indexOf('*') >=
0);
+ }
+
}