好的,所以我为Eclipse写了一个插件(好吧,所以它主要是从ADT复制的代码)。它是一个新的项目向导,与ADT的新项目向导基本相同,只是它复制到库中,将其添加到构建路径,并复制到其他一些文件。一切正常。
该库名为AltBridge,它是从App Inventor的Java Bridge库构建的。这个库本质上改变了你稍微编写一个活动的方式,我想添加一个菜单选项来创建一个新的Form(这是一个修改过的Activity)。
这就是Eclipse令人烦恼的地方。如果我点击F11,我可以正常工作。它创建新文件没问题。但是,当我导出插件并尝试它时,它不起作用。
这是我到目前为止所拥有的:
public class NewFormMenuSelection extends AbstractHandler implements IHandler {
private static final String PARAM_PACKAGE = "PACKAGE";
private static final String PARAM_ACTIVITY = "ACTIVITY_NAME";
private static final String PARAM_IMPORT_RESOURCE_CLASS = "IMPORT_RESOURCE_CLASS";
private Map<String, Object> java_activity_parameters = new HashMap<String, Object>();
public Object execute(ExecutionEvent event) throws ExecutionException {
IStructuredSelection selection = (IStructuredSelection) HandlerUtil
.getActiveMenuSelection(event);
String directory = "";
Object firstElement = selection.getFirstElement();
if (firstElement instanceof IPackageFragment) {
InputDialog dialog = new InputDialog(HandlerUtil.getActiveShell(event), "Name of the new Form to create?", "Please enter the name of the new form to create.", "NewForm", null);
if ( dialog.open()==IStatus.OK ) {
String activityName = dialog.getValue();
String packageName = ((IPackageFragment) firstElement).getElementName();
if (activityName != null) {
String resourcePackageClass = null;
// An activity name can be of the form ".package.Class", ".Class" or FQDN.
// The initial dot is ignored, as it is always added later in the templates.
int lastDotIndex = activityName.lastIndexOf('.');
if (lastDotIndex != -1) {
// Resource class
if (lastDotIndex > 0) {
resourcePackageClass = packageName + "." + AdtConstants.FN_RESOURCE_BASE; //$NON-NLS-1$
}
// Package name
if (activityName.startsWith(".")) { //$NON-NLS-1$
packageName += activityName.substring(0, lastDotIndex);
} else {
packageName = activityName.substring(0, lastDotIndex);
}
// Activity Class name
activityName = activityName.substring(lastDotIndex + 1);
}
java_activity_parameters.put(PARAM_IMPORT_RESOURCE_CLASS, "");
java_activity_parameters.put(PARAM_ACTIVITY, activityName);
java_activity_parameters.put(PARAM_PACKAGE, packageName);
if (resourcePackageClass != null) {
String importResourceClass = "\nimport " + resourcePackageClass + ";"; //$NON-NLS-1$ // $NON-NLS-2$
java_activity_parameters.put(PARAM_IMPORT_RESOURCE_CLASS, importResourceClass);
}
if (activityName != null) {
// create the main activity Java file
// get the path of the package
IPath path = ((IPackageFragment) firstElement).getPath();
String pkgpath = path.toString();
// Get the project name
String activityJava = activityName + AdtConstants.DOT_JAVA;
String projname = ((IPackageFragment) firstElement).getParent().getJavaProject().getElementName();
// Get the project
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projname);
IFolder pkgFolder = project.getFolder(pkgpath);
IFile file = pkgFolder.getFile(activityJava);
if (!file.exists()) {
try {
copyFile("java_file.template", file, java_activity_parameters, false);
} catch (CoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
return null;
}
private void copyFile(String resourceFilename, IFile destFile,
Map<String, Object> parameters, boolean reformat)
throws CoreException, IOException {
// Read existing file.
String template = AltBridge.readEmbeddedTextFile(
"templates/" + resourceFilename);
// Replace all keyword parameters
template = replaceParameters(template, parameters);
if (reformat) {
// Guess the formatting style based on the file location
XmlFormatStyle style = XmlFormatStyle.getForFile(destFile.getProjectRelativePath());
if (style != null) {
template = reformat(style, template);
}
}
// Save in the project as UTF-8
InputStream stream = new ByteArrayInputStream(template.getBytes("UTF-8")); //$NON-NLS-1$
destFile.create(stream, true /* force */, null);
}
private String replaceParameters(String str, Map<String, Object> parameters) {
if (parameters == null) {
AltBridge.log(IStatus.ERROR,
"NPW replace parameters: null parameter map. String: '%s'", str); //$NON-NLS-1$
return str;
} else if (str == null) {
AltBridge.log(IStatus.ERROR,
"NPW replace parameters: null template string"); //$NON-NLS-1$
return str;
}
for (Entry<String, Object> entry : parameters.entrySet()) {
if (entry != null && entry.getValue() instanceof String) {
Object value = entry.getValue();
if (value == null) {
AltBridge.log(IStatus.ERROR,
"NPW replace parameters: null value for key '%s' in template '%s'", //$NON-NLS-1$
entry.getKey(),
str);
} else {
str = str.replaceAll(entry.getKey(), (String) value);
}
}
}
return str;
}
private String reformat(XmlFormatStyle style, String contents) {
if (AdtPrefs.getPrefs().getUseCustomXmlFormatter()) {
XmlFormatPreferences formatPrefs = XmlFormatPreferences.create();
return XmlPrettyPrinter.prettyPrint(contents, formatPrefs, style,
null /*lineSeparator*/);
} else {
return contents;
}
}
我似乎遇到问题的部分是在//创建主要活动java文件的地方。
为了让它在击中F11时起作用,我不得不放弃包的前两个条目(我知道我可能已经做了更好的方法,但它有效)。否则,由于某种原因,它将项目名称添加到开头的路径(加倍)。如果这样离开,在导出和在测试环境之外尝试时它将无法工作。它给出一个错误,指出项目名称必须在路径中。因此,如果我删除了删除它的部分,它在按F11时不起作用,并且在构建环境之外,它不起作用,并且不会产生任何类型的错误。关于我可能做错的任何线索?
这是复制文件代码(同样,这只是从ADT插件中复制而来):
public static String readEmbeddedTextFile(String filepath) {
try {
InputStream is = readEmbeddedFileAsStream(filepath);
if (is != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line;
StringBuilder total = new StringBuilder(reader.readLine());
while ((line = reader.readLine()) != null) {
total.append('\n');
total.append(line);
}
return total.toString();
}
} catch (IOException e) {
// we'll just return null
AltBridge.log(e, "Failed to read text file '%s'", filepath); //$NON-NLS-1$
}
return null;
}
public static InputStream readEmbeddedFileAsStream(String filepath) {
// attempt to read an embedded file
try {
URL url = getEmbeddedFileUrl(AdtConstants.WS_SEP + filepath);
if (url != null) {
return url.openStream();
}
} catch (MalformedURLException e) {
// we'll just return null.
AltBridge.log(e, "Failed to read stream '%s'", filepath); //$NON-NLS-1$
} catch (IOException e) {
// we'll just return null;.
AltBridge.log(e, "Failed to read stream '%s'", filepath); //$NON-NLS-1$
}
return null;
}
public static URL getEmbeddedFileUrl(String filepath) {
Bundle bundle = null;
synchronized (AltBridge.class) {
if (plugin != null) {
bundle = plugin.getBundle();
} else {
AltBridge.log(IStatus.WARNING, "ADT Plugin is missing"); //$NON-NLS-1$
return null;
}
}
// attempt to get a file to one of the template.
String path = filepath;
if (!path.startsWith(AdtConstants.WS_SEP)) {
path = AdtConstants.WS_SEP + path;
}
URL url = bundle.getEntry(path);
if (url == null) {
AltBridge.log(IStatus.INFO, "Bundle file URL not found at path '%s'", path); //$NON-NLS-1$
}
return url;
}
好的,问题似乎与IProject或IFolder有关。例如,路径以“test / src / com / test”的形式返回。然后,当我使用pkgfolder.getFile时,它会在路径前添加另一个/ test /(这是在eclipse中按F11进行测试时)。
答案 0 :(得分:1)
好吧,我当然让它变得更加复杂。这是我用过的代码。 (我仍然不明白为什么Eclipse表现得如此奇怪......为什么在使用F11进行测试时会有效,但是在部署插件时却没有?)。
这也只是//创建主要活动Java文件的部分:
if (activityName != null) {
// create the main activity Java file
String activityJava = activityName + AdtConstants.DOT_JAVA;
// Get the path of the package
IPath path = ((IPackageFragment) firstElement).getPath();
String pkgpath = path.toString();
String projname = "";
// Remove the project name from the beginning of the path
String temp[] = pkgpath.split("/");
pkgpath = "";
for (int i = 1; i < temp.length; i++) {
if (i==1) {
pkgpath = "/";
projname = temp[i];
} else {
pkgpath = pkgpath + "/" + temp[i];
}
}
// Get the project
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projname);
IFile file = project.getFile(pkgpath+"/"+activityJava);
if (!file.exists()) {
try {
copyFile("java_file.template", file, java_activity_parameters);
} catch (CoreException e) {
AltBridge.log(e, "Couldn't copy the text file", pkgpath);
e.printStackTrace();
} catch (IOException e) {
AltBridge.log(e, "Couldn't copy the text file", pkgpath);
e.printStackTrace();
}
}
}
答案 1 :(得分:0)
要管理包中的文件,您需要使用Eclipse的Bundle class。我的PhoneGap项目创建向导中有一个示例,它位于bundleCopy方法here中。
答案 2 :(得分:0)
好的,问题似乎与IProject或IFolder有关。路径得到了 例如,以“test / src / com / test”返回。然后,当我使用 pkgfolder.getFile,它在路径前添加了另一个/ test /(这个 是在eclipse中按F11测试的。)
因此,如果路径是test / src / com / test,那么test必须是项目。使用IWorkspaceRoot.findMember(path)。并在路径前放一个“/”。没有必要去寻找项目/文件夹等其他东西。