This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 167205 - Unable to edit empty file template
Summary: Unable to edit empty file template
Status: RESOLVED FIXED
Alias: None
Product: platform
Classification: Unclassified
Component: Templates (show other bugs)
Version: 6.x
Hardware: Macintosh All
: P3 blocker (vote)
Assignee: Martin Entlicher
URL:
Keywords: API, API_REVIEW_FAST
Depends on:
Blocks: 65037 188578
  Show dependency tree
 
Reported: 2009-06-17 09:06 UTC by shiretu
Modified: 2012-11-21 13:38 UTC (History)
5 users (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments
The suggested patch with CND template attributes. (41.76 KB, patch)
2010-11-03 17:12 UTC, Martin Entlicher
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description shiretu 2009-06-17 09:06:47 UTC
Hi,

We can edit C++ header file template by going to Tools->Templates, expand C++ tree and select C++ header file. After that click Open in editor. Why is not 
possible with C++ source file? The Open in editor button is deactivated


Thank you
Comment 1 Vladimir Voskresensky 2009-06-17 17:48:28 UTC
Something is wrong in templates support.

C++ source file && C source file are empty files (empty-cc.template && empty-c.template)

trunk/cnd/src/org/netbeans/modules/cnd/resources/templates/cpp/empty-cc.template

if I put at least space in empty-cc.template file => button is activated
Comment 2 Alexander Simon 2009-06-17 18:22:26 UTC
IMHO it is wrong to have empty template.
I propose add "new line" in the templates.
It complies with C/C++ specification.
Comment 3 rmichalsky 2009-06-18 09:47:24 UTC
> I propose add "new line" in the templates.
> It complies with C/C++ specification.

Ok, reassigning to cnd. Feel free to return it back if you have a reason not to change template files.
Comment 4 Vladimir Voskresensky 2009-06-18 10:09:19 UTC
I'd like to see it to be fixed on general level. 
Do not see any reasons to *prohibit* editing of empty template file. 
There are a lot of such templates in IDE already and users' plugins add some more as well.
#find . -name "*.template" -exec wc -l {} \; | grep -v "/build/" | grep " 0 \."
       0 ./cnd/src/org/netbeans/modules/cnd/resources/templates/c/empty-c.template
       0 ./cnd/src/org/netbeans/modules/cnd/resources/templates/cpp/empty-cc.template
       0 ./cnd/src/org/netbeans/modules/cnd/resources/templates/fortran/empty-f90.template
       0 ./dbschema/src/org/netbeans/modules/dbschema/jdbcimpl/resources/templates/Database Schema.template
       0 ./dbschema/src/org/netbeans/modules/dbschema/jdbcimpl/resources/templates/Schema.template
       0 ./j2ee.sun.appsrv/src/org/netbeans/modules/j2ee/sun/ide/sunresources/wizards/ResourceWizard.template
       0 ./java.project/src/org/netbeans/modules/java/project/resources/Empty.template
       0 ./java.project/src/org/netbeans/modules/java/project/resources/Package.template
       0 ./java.source/src/org/netbeans/modules/java/resources/templates/Empty.template
       0 ./java.source/src/org/netbeans/modules/java/resources/templates/Package.template
       0 ./web.core/src/org/netbeans/modules/web/core/resources/templates/WebModule.template
       0 ./web.jsf/src/org/netbeans/modules/web/jsf/resources/templates/dummy.template
       0 ./websvc.rest/src/org/netbeans/modules/websvc/rest/codegen/resources/JmakiComponentHtm.template
       0 ./websvc.rest/src/org/netbeans/modules/websvc/rest/codegen/resources/JmakiRestBundle.template
Comment 5 rmichalsky 2009-06-18 13:56:20 UTC
I found out that this is actually, according to issue #65037, a desired behavior. However I don't understand, what is
the purpose of "empty pseudotemplates" present in template manager, CC-ing Jesse since he proposed disabling the button
on empty templates. Maybe we could add an attribute indicating "pseudotemplate", whatever it is?
Comment 6 shiretu 2009-06-18 14:55:35 UTC
Hi,

If you want an outside user opinions regarding issue #65037, here they are:

1. It is absurd not to have a template for C++ source files. This defeats the very purpose of having that listed in the available templates. Why showing it 
there if it is impossible to use/modify!?

2. It would be nice to have a way to define/edit/use a template for any file type we want. For example, I add the copyright notice manually every time I 
create a cpp file. Which IMHO is not OK.

3. If I decide later to get rid of template's content, I normally delete the template's content and fall into a "gotcha": I wont be able to edit the template again 
later. I must know that I have to enter at least an empty line (hence, I must follow this bug report site to know about it, which is not OK either)

Thank you
Comment 7 shiretu 2009-06-18 15:15:54 UTC
Another thing... If I manually create file.c in ~/.netbeans/6.7rc3/config/Templates/cFiles I can edit the C source file template. 
The same approach of tricking the netbeans doesn't work with ~/.netbeans/6.7rc3/config/Templates/cppFiles directory (C++ source files). I've created the 
following files: file.cpp, file.cc, file.cxx
None of them gives me access to the template editor for C++ source files
Comment 8 Jesse Glick 2009-06-18 16:53:08 UTC
There are three kinds of templates, i.e. non-dir entries under Templates/:

1. Files with no special attrs. These get a generic wizard panel and are copied as is to the user's project. Or they may
ask to be processed using e.g. FreeMarker, but no module code is involved. Usually nonempty, but may be empty if the
template exists solely as a placeholder for a display label and a file extension. Example: HTML file.

2. Files with real contents but also a instantiating iterator. These get a custom wizard panel but the file's content is
also used (somehow). Example: Java source file; sample project ZIP.

3. Files used solely as placeholders for an instantiating iterator (i.e. custom wizard panel). In this case the
"template"'s content is ignored and is usually empty. The result might even be multiple files, etc. Example: XML file
(where you asked for well-formed doc, etc.); empty project.

Issue #65037 was filed because there were many empty files in the third category; editing the "template" contents is
meaningless and misleading. Empty files in the first category were not affected. Unfortunately there are apparently also
some empty files in the second category, which cannot currently be distinguished mechanically from the third. Making
such a distinction will require an API change (such as a new file attribute) and I don't think it can be backward
compatible - i.e. we either need to mark third-category files (meaning #65037 will be reverted for older unmarked
examples) or we need to mark second-category files (meaning this issue will remain unfixed for older unmarked examples).
Comment 9 rmichalsky 2009-06-19 15:06:40 UTC
> we need to mark second-category files (meaning this issue will remain unfixed for older unmarked examples).

That sounds like a correct choice for me, I am not sure what would remain unfixed. Do you mean the case when someone
deleted content of the (2nd category) template, which is now stored in userdir, thus would not be marked with new attribute?

Or perhaps we could let template's instantiatingIterator optionally implement a tagging interface, e.g.
IUsesTemplateFileContent, qualifying its templates for user editing. "Open in Editor" button would then probably be
enabled by default and check this only when clicked so that whole bunch of classes would not get loaded when Template
Manager is shown.
Comment 10 Jesse Glick 2009-06-19 15:23:55 UTC
"I am not sure what would remain unfixed" - an older module with an empty 2nd-cat template would still not enable the
Edit button; the module would need to be updated.

A new interface for the value of attrs 'templateWizardIterator' or 'instantiatingIterator' sounds OK to me. Rather than
an empty marker interface, which is bad because you cannot unimplement an interface from a superclass or proxy, it
should have a boolean method. For example, a new nested type in TemplateWizard:

/**
 * May be implemented by {@link WizardDescriptor.InstantiatingIterator} or {@link TemplateWizard.Iterator} impls.
 */
public interface EditableTemplateIterator {
  /**
   * If interface absent, the fallback algorithm is:
   * <ol>
   * <li>true if there is no iterator at all</li>
   * <li>true if the template file has nonzero length</li>
   * <li>false otherwise</li>
   * </ol>
   * @return true if it makes sense for the user to edit this template
   */
  boolean isTemplateEditable(FileObject template);
}

The interface could live inside WizardDescriptor but then it could not take a template param; not sure if that matters
in practice.
Comment 11 rmichalsky 2009-06-19 16:57:50 UTC
> public interface EditableTemplateIterator { ...

Could do it. But isn't there the same problem as you describe with new attr? That template from old module still would
not be editable... I assume the same module that registers the template implements its iterator. 
Comment 12 Jesse Glick 2009-06-19 17:31:14 UTC
Right, a template from an old module would not be editable if zero-length, so modules would still need to be updated
wherever possible. I don't think that can be avoided.

It is not necessarily the case that the provider of a template also implements the iterator. Many modules provide *.java
templates, but these all use a single iterator impl (in java.source IIRC). This is a good sign - it is the iterator impl
which knows for sure whether or not it reads the byte stream from the associated template file, and therefore whether
opening that file in the editor is sensible or not.


Note that you can have a nonempty template file which is read by the iterator which is still not amenable to an Edit
button, if its content is binary, such as a ZIP. We could consider a more general interface with three choices (not sure
about Java signature, would be easier in a language with algebraic data types):

1. Enable Edit button; if clicked, open template in editor as now. (Using OpenCookie I suppose.)

2. Enable Edit button; if clicked, perform arbitrary action supplied by iterator. (Might let you edit ZIP content in a
file tree etc.)

3. Disable Edit button.

I am not sure if there is an actual use case for non-text customization, however.
Comment 13 Quality Engineering 2009-06-20 08:05:44 UTC
Integrated into 'main-golden', will be available in build *200906200201* on http://bits.netbeans.org/dev/nightly/ (upload may still be in progress)
Changeset: http://hg.netbeans.org/main-golden/rev/1f0342103091
User: Richard Michalsky <rmichalsky@netbeans.org>
Log: cleanup after #167205: property checking equals -> isfalse
Comment 14 rmichalsky 2009-06-24 15:29:25 UTC
Sorry for the qa comment above, I've filled in wrong issue number in commit.

Ok, so the iface would look like, e.g.:

    public static interface EditableTemplateIterator {
        public enum OpenType {
            OPEN_VIA_OPEN_COOKIE,
            OPEN_CUSTOM,
            DONT_OPEN
        };

        /**
         * Queried from TemplateManager if and how can be given template edited by user.
         * ...
         */
        public OpenType canOpenTemplate(FileObject template);
        /**
         * Called to perform custom template editing when <code>OPEN_CUSTOM</code>
         * returned from {@link #canOpenTemplate}.
         * ...
         * @param template
         */
        public void performCustomOpen(FileObject template);
    }

and I'd either figure out or ask the maintainers which templates make sense to be editable. 

Not sure if it gets into 6.8, if time permits.
Comment 15 Jesse Glick 2009-06-24 20:20:30 UTC
Yes, something like that.
Comment 16 Martin Entlicher 2010-11-03 17:04:50 UTC
The suggested EditableTemplateIterator looks too heavyweight to me.
IMHO the easiest approach would be to introduce "templateCanEdit" attribute that can be easily declared for the template file in the module layer. It can have Boolean.TRUE or Boolean.FALSE value and "Open in editor" button would be enabled/disabled accordingly.

To provide custom edit action, we can have "templateEditable" attribute that would provide an instance of Editable.

The attached patch interprets the two attributes "templateCanEdit" and "templateEditable". Also it introduces arch.xml which describes these attributes.
Comment 17 Martin Entlicher 2010-11-03 17:12:47 UTC
Created attachment 102782 [details]
The suggested patch with CND template attributes.

Patch with CND template attributes attached, attributes "templateCanEdit" will be added for all other templates listed in this issue.
Comment 18 Jesse Glick 2010-11-03 17:35:56 UTC
[JG01] API group should be layer, not property. (Better would be to define public constants in an appropriate API module; unfortunately template handling is strewn across openide.loaders, favorites, openide.dialogs, and projectui. Anyway once there is an annotation to register templates it will not be necessary to find a place to document all the available properties.)


[JG02] The new attributes should be added to FileUtil.transientAttributes.


Misc: the code

if (Boolean.TRUE.equals(canEdit)) {
    res = true;
    continue;
}
if (Boolean.FALSE.equals(canEdit)) {
    res = false;
    continue;
}

can be simplified using autoboxing to:

if (canEdit != null) {
    res = (Boolean) canEdit;
    continue;
}
Comment 19 Jaroslav Tulach 2010-11-04 13:24:38 UTC
Btw. can't you just put "\n" into the template files? E.g. make them non-empty?
Comment 20 Jesse Glick 2010-11-04 14:17:29 UTC
(In reply to comment #19)
> can't you just put "\n" into the template files?

Not a bad idea. Certainly simpler than any of the other proposals.

(To protect against the possibility that some over-clever user edits the template, deletes the \n, saves, and then can't edit it again, just check also for template.getAttribute("removeWritables") != null.)
Comment 21 Martin Entlicher 2010-11-04 14:25:08 UTC
Currently the check is "FileUtil.toFile (fo) != null || fo.getSize () > 0", therefore if anyone edits the file, they will always be able to edit it again.

If it's feasible to add '\n' to all empty templates, then we can discard this patch. Or we can reduce it just to "templateEditable" attribute.
Comment 22 Jesse Glick 2010-11-04 14:45:47 UTC
(In reply to comment #21)
> Currently the check is "FileUtil.toFile (fo) != null || fo.getSize () > 0"

Works if you make certain assumptions about how layers and the userdir are represented, but checking for removeWritables is more general.

> If it's feasible to add '\n' to all empty templates

I think it's feasible; worth trying. Rather than adding \n you can also insert some type-dependent placeholder content such as

---%<---
// TODO write code
---%<---

In some cases it may also make sense to include a license header even for an "empty" template. In other cases we may decide that an empty template is useless; for example, Templates/Classes/Empty.java is sort of pointless because an empty file is syntactically invalid to begin with, i.e. you need to at least have a class declaration to even satisfy the compiler.

Note that Package.template currently has text contents which it need not; delete resources/Package.template and remove the url=... attr from the layer.

Vladimir's search is actually finding the wrong thing: people who created an empty file in the NB source tree and then referred to it via url=..., which is a no-op. All these should be deleted regardless of this issue. (ValidateLayerConsistencyTest could help.) Also, the filename *.template is quite arbitrary and not consistently used.

What you really want to do is search the system filesystem under Templates/ for files marked template=true with zero length and no template iterator. These will not be editable but probably ought to be, thus a problem; this is something ValidateLayerConsistencyTest can be made to verify. It will not find cases like Package.template where the template has text contents for no reason and ought not be editable. It will also not find cases like Empty.java where the template is empty and has a template iterator, but the iterator reads the text contents and the template ought to be editable; these would have been handled by my original proposal (since the template iterator, not the template, is responsible for reporting whether it uses template contents), but I guess we can find such cases by hand.
Comment 23 Vladimir Voskresensky 2010-11-05 09:46:08 UTC
(In reply to comment #19)
> Btw. can't you just put "\n" into the template files? E.g. make them non-empty?

We already changed all cnd templates to be have not zero size.
Comment 24 Martin Entlicher 2012-04-17 16:00:49 UTC
I've replaced the condition "FileUtil.toFile (fo) != null" with more reliable fo.canRevert().

Since the empty templates that should be editable were made non-empty already, I think we can close this issue.
Comment 25 Jesse Glick 2012-04-17 22:02:41 UTC
(In reply to comment #24)
> the empty templates that should be editable were made non-empty already

Some perhaps, but not all. I implemented the check described in comment #22 and it fails (at least in "SQL file"). Committing in commented-out form (core-main #ccbd7750e319); someone needs to uncomment it after dealing with the current failures in cluster.config=full.
Comment 26 Quality Engineering 2012-04-18 21:26:50 UTC
Integrated into 'main-golden', will be available in build *201204181547* on http://bits.netbeans.org/dev/nightly/ (upload may still be in progress)
Changeset: http://hg.netbeans.org/main-golden/rev/9e5317b9b16a
User: mentlicher@netbeans.org
Log: #167205: FileObject.canRevert() is more reliable replacement for FileUtil.toFile(fo) != null.
Comment 27 Martin Entlicher 2012-11-19 13:26:49 UTC
Remaining templates were made non-empty and the test was enabled:
changeset:   240276:f4a2aa04a500
http://hg.netbeans.org/core-main/rev/f4a2aa04a500
Thanks.
Comment 28 Quality Engineering 2012-11-21 13:38:33 UTC
Integrated into 'main-golden', will be available in build *201211211016* on http://bits.netbeans.org/dev/nightly/ (upload may still be in progress)
Changeset: http://hg.netbeans.org/main-golden/rev/f4a2aa04a500
User: mentlicher@netbeans.org
Log: #167205: Editable templates made non-empty and the appropriate test is uncommented.