// 
//     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.
//

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

=== How can I programmatically modify a Java source file?

Most modifications are done through the API. Direct document changes are not recommended. Editing source through the API has many advantages, for instance it respects formatting settings. 

This part will show you typical steps to make a modification to your source. There can be found different usecases, but this is the most common:

* Find the JavaSource you want to work with,
* create a task that contains code for source modification,
* post the task to the JavaSource and commit the changes at the end.

TODO: link to example, describe what the example does.

==== Find the JavaSource

There are more ways to do it. For our demonstration, we use a straightforward solution, often used in tests. We omit the details of getting fileObject and we expect successful behaviour of called methods.

[source,java]
----

    File tutorialFile = getFile(getSourceDir(), "/org/netbeans/test/codegen/Tutorial1.java");
    JavaSource tutorialSource = JavaSource.forFileObject(FileUtil.toFileObject(tutorialFile));
----

The JavaSource represents the file `Tutorial1.java` in package `org.netbeans.test.codegen`.

==== Create a 'modify' task

`Task` is a parameterized interface with type parameter `WorkingCopy`. This type is requested in the next step. This next code snippet shows how to create an anonymous `Task`:

[source,java]
----

    Task task = new Task<WorkingCopy>() {
        ...
    }
----

The interface contains run method that contains code for modifying our javaSource.

[source,java]
----

    Task task = new Task<WorkingCopy>() {

        public void run(WorkingCopy workingCopy) throws Exception {
            ... our modification code
        }

    };
----

The run method contains all staff describing modification and we will dive in to the details later.

==== Post the task to process and commit the changes

Because we want to modify the source, we have to use runModificationTask (see its javadoc). At the end, we have to commit changes to propagate all the work to the source file - our `Tutorial1.java` file. This can fail, so ensure you correctly handle exceptions. The method `runModificationTask()` returns the modification result. This class contains all the prepared changes which haven't been propagated yet. This is good especially when someone wants to review the details of modification and decide about propagating changes to the source on the basis of `result`. For our demonstration, we will omit it. When `result` is collected, we have to call the `commit()` method to propagate the changes to the source code:

[source,java]
----

    ModificationResult result = tutorialSource.runModificationTask(task);
    result.commit();
----

=== 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/JavaHT[http://wiki.netbeans.org/JavaHT] Modification , 
that was last modified by NetBeans user Tboudreau 
on 2010-02-25T16:24:21Z.


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