// 
//     Licensed to the Apache Software Foundation (ASF) under one
//     or more contributor license agreements.  See the NOTICE file
//     distributed with this work for additional information
//     regarding copyright ownership.  The ASF licenses this file
//     to you under the Apache License, Version 2.0 (the
//     "License"); you may not use this file except in compliance
//     with the License.  You may obtain a copy of the License at
// 
//       http://www.apache.org/licenses/LICENSE-2.0
// 
//     Unless required by applicable law or agreed to in writing,
//     software distributed under the License is distributed on an
//     "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
//     KIND, either express or implied.  See the License for the
//     specific language governing permissions and limitations
//     under the License.
//

= DevFaqAddDoingEvilThingsToForeignNodes
:jbake-type: wiki
:jbake-tags: wiki, devfaq, needsreview
:jbake-status: published
:keywords: Apache NetBeans wiki DevFaqAddDoingEvilThingsToForeignNodes
:description: Apache NetBeans wiki DevFaqAddDoingEvilThingsToForeignNodes
:toc: left
:toc-title:
:syntax: true

=== I have a reference to an existing Node from some other module. Can I add cookies/properties/actions/children?

No.

Occasionally people want to do something like this, because they want to enhance, for example, the behavior or nodes for Java files or other nodes created by some other modules.  However, this is a recipe for disaster - nobody writing a Node subclass does so expecting that random modules will change its internal structures without warning.  It is possible to write code that does this sort of thing that looks like it works, but it is sheer luck and it will probably not work for long.  

==== *_DO NOT DO THAT UNDER ANY CIRCUMSTANCES_*

(there, did I say that strongly enough?).

Many modules are designed for extensibility - in fact, Nodes for Java files in the IDE do allow you to add children, actions, etc.  They offer an API for doing this sort of thing (for example, adding Actions to `Loaders/text/x-java/Actions` declaratively);  see the beans module for an example of adding sub-nodes to Java classes.

If you want to modify the children/properties/actions/etc. of a Node you did not create, look for an API that lets you do that in a supported way.  

If one does not exist, link:http://www.netbeans.org/issues/enter_bug.cgi[file an enhancement request] against the module that actually creates these nodes, asking for an appropriate API for doing what you want (and be clear about exactly what you want or why).  If you really want to expedite it, write a patch that creates such an API (look at how other modules do this sort of thing and aim to follow a similar pattern) - it's hard to say no to working code.

=== Apache Migration Information

The content in this page was kindly donated by Oracle Corp. to the
Apache Software Foundation.

This page was exported from link:http://wiki.netbeans.org/DevFaqAddDoingEvilThingsToForeignNodes[http://wiki.netbeans.org/DevFaqAddDoingEvilThingsToForeignNodes] , 
that was last modified by NetBeans user Admin 
on 2009-11-06T15:36:02Z.


*NOTE:* This document was automatically converted to the AsciiDoc format on 2018-02-07, and needs to be reviewed.
