1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/docker.api/external/binaries-list Thu Mar 24 15:34:03 2016 +0100
1.3 @@ -0,0 +1,1 @@
1.4 +C17B8FF394BF8C8C786D43710CE4C3995C803E82 juds-0.95.jar
1.5 \ No newline at end of file
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/docker.api/external/juds-0.95-license.txt Thu Mar 24 15:34:03 2016 +0100
2.3 @@ -0,0 +1,507 @@
2.4 +Name: juds
2.5 +Version: 0.95
2.6 +OSR: TBD
2.7 +License: LGPL-2.1
2.8 +Description: Java Unix Domain Sockets
2.9 +Origin: https://github.com/mcfunley/juds
2.10 +
2.11 + GNU LESSER GENERAL PUBLIC LICENSE
2.12 + Version 2.1, February 1999
2.13 +
2.14 + Copyright (C) 1991, 1999 Free Software Foundation, Inc.
2.15 + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2.16 + Everyone is permitted to copy and distribute verbatim copies
2.17 + of this license document, but changing it is not allowed.
2.18 +
2.19 +[This is the first released version of the Lesser GPL. It also counts
2.20 + as the successor of the GNU Library Public License, version 2, hence
2.21 + the version number 2.1.]
2.22 +
2.23 + Preamble
2.24 +
2.25 + The licenses for most software are designed to take away your
2.26 +freedom to share and change it. By contrast, the GNU General Public
2.27 +Licenses are intended to guarantee your freedom to share and change
2.28 +free software--to make sure the software is free for all its users.
2.29 +
2.30 + This license, the Lesser General Public License, applies to some
2.31 +specially designated software packages--typically libraries--of the
2.32 +Free Software Foundation and other authors who decide to use it. You
2.33 +can use it too, but we suggest you first think carefully about whether
2.34 +this license or the ordinary General Public License is the better
2.35 +strategy to use in any particular case, based on the explanations below.
2.36 +
2.37 + When we speak of free software, we are referring to freedom of use,
2.38 +not price. Our General Public Licenses are designed to make sure that
2.39 +you have the freedom to distribute copies of free software (and charge
2.40 +for this service if you wish); that you receive source code or can get
2.41 +it if you want it; that you can change the software and use pieces of
2.42 +it in new free programs; and that you are informed that you can do
2.43 +these things.
2.44 +
2.45 + To protect your rights, we need to make restrictions that forbid
2.46 +distributors to deny you these rights or to ask you to surrender these
2.47 +rights. These restrictions translate to certain responsibilities for
2.48 +you if you distribute copies of the library or if you modify it.
2.49 +
2.50 + For example, if you distribute copies of the library, whether gratis
2.51 +or for a fee, you must give the recipients all the rights that we gave
2.52 +you. You must make sure that they, too, receive or can get the source
2.53 +code. If you link other code with the library, you must provide
2.54 +complete object files to the recipients, so that they can relink them
2.55 +with the library after making changes to the library and recompiling
2.56 +it. And you must show them these terms so they know their rights.
2.57 +
2.58 + We protect your rights with a two-step method: (1) we copyright the
2.59 +library, and (2) we offer you this license, which gives you legal
2.60 +permission to copy, distribute and/or modify the library.
2.61 +
2.62 + To protect each distributor, we want to make it very clear that
2.63 +there is no warranty for the free library. Also, if the library is
2.64 +modified by someone else and passed on, the recipients should know
2.65 +that what they have is not the original version, so that the original
2.66 +author's reputation will not be affected by problems that might be
2.67 +introduced by others.
2.68 +
2.69 + Finally, software patents pose a constant threat to the existence of
2.70 +any free program. We wish to make sure that a company cannot
2.71 +effectively restrict the users of a free program by obtaining a
2.72 +restrictive license from a patent holder. Therefore, we insist that
2.73 +any patent license obtained for a version of the library must be
2.74 +consistent with the full freedom of use specified in this license.
2.75 +
2.76 + Most GNU software, including some libraries, is covered by the
2.77 +ordinary GNU General Public License. This license, the GNU Lesser
2.78 +General Public License, applies to certain designated libraries, and
2.79 +is quite different from the ordinary General Public License. We use
2.80 +this license for certain libraries in order to permit linking those
2.81 +libraries into non-free programs.
2.82 +
2.83 + When a program is linked with a library, whether statically or using
2.84 +a shared library, the combination of the two is legally speaking a
2.85 +combined work, a derivative of the original library. The ordinary
2.86 +General Public License therefore permits such linking only if the
2.87 +entire combination fits its criteria of freedom. The Lesser General
2.88 +Public License permits more lax criteria for linking other code with
2.89 +the library.
2.90 +
2.91 + We call this license the "Lesser" General Public License because it
2.92 +does Less to protect the user's freedom than the ordinary General
2.93 +Public License. It also provides other free software developers Less
2.94 +of an advantage over competing non-free programs. These disadvantages
2.95 +are the reason we use the ordinary General Public License for many
2.96 +libraries. However, the Lesser license provides advantages in certain
2.97 +special circumstances.
2.98 +
2.99 + For example, on rare occasions, there may be a special need to
2.100 +encourage the widest possible use of a certain library, so that it becomes
2.101 +a de-facto standard. To achieve this, non-free programs must be
2.102 +allowed to use the library. A more frequent case is that a free
2.103 +library does the same job as widely used non-free libraries. In this
2.104 +case, there is little to gain by limiting the free library to free
2.105 +software only, so we use the Lesser General Public License.
2.106 +
2.107 + In other cases, permission to use a particular library in non-free
2.108 +programs enables a greater number of people to use a large body of
2.109 +free software. For example, permission to use the GNU C Library in
2.110 +non-free programs enables many more people to use the whole GNU
2.111 +operating system, as well as its variant, the GNU/Linux operating
2.112 +system.
2.113 +
2.114 + Although the Lesser General Public License is Less protective of the
2.115 +users' freedom, it does ensure that the user of a program that is
2.116 +linked with the Library has the freedom and the wherewithal to run
2.117 +that program using a modified version of the Library.
2.118 +
2.119 + The precise terms and conditions for copying, distribution and
2.120 +modification follow. Pay close attention to the difference between a
2.121 +"work based on the library" and a "work that uses the library". The
2.122 +former contains code derived from the library, whereas the latter must
2.123 +be combined with the library in order to run.
2.124 +
2.125 + GNU LESSER GENERAL PUBLIC LICENSE
2.126 + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
2.127 +
2.128 + 0. This License Agreement applies to any software library or other
2.129 +program which contains a notice placed by the copyright holder or
2.130 +other authorized party saying it may be distributed under the terms of
2.131 +this Lesser General Public License (also called "this License").
2.132 +Each licensee is addressed as "you".
2.133 +
2.134 + A "library" means a collection of software functions and/or data
2.135 +prepared so as to be conveniently linked with application programs
2.136 +(which use some of those functions and data) to form executables.
2.137 +
2.138 + The "Library", below, refers to any such software library or work
2.139 +which has been distributed under these terms. A "work based on the
2.140 +Library" means either the Library or any derivative work under
2.141 +copyright law: that is to say, a work containing the Library or a
2.142 +portion of it, either verbatim or with modifications and/or translated
2.143 +straightforwardly into another language. (Hereinafter, translation is
2.144 +included without limitation in the term "modification".)
2.145 +
2.146 + "Source code" for a work means the preferred form of the work for
2.147 +making modifications to it. For a library, complete source code means
2.148 +all the source code for all modules it contains, plus any associated
2.149 +interface definition files, plus the scripts used to control compilation
2.150 +and installation of the library.
2.151 +
2.152 + Activities other than copying, distribution and modification are not
2.153 +covered by this License; they are outside its scope. The act of
2.154 +running a program using the Library is not restricted, and output from
2.155 +such a program is covered only if its contents constitute a work based
2.156 +on the Library (independent of the use of the Library in a tool for
2.157 +writing it). Whether that is true depends on what the Library does
2.158 +and what the program that uses the Library does.
2.159 +
2.160 + 1. You may copy and distribute verbatim copies of the Library's
2.161 +complete source code as you receive it, in any medium, provided that
2.162 +you conspicuously and appropriately publish on each copy an
2.163 +appropriate copyright notice and disclaimer of warranty; keep intact
2.164 +all the notices that refer to this License and to the absence of any
2.165 +warranty; and distribute a copy of this License along with the
2.166 +Library.
2.167 +
2.168 + You may charge a fee for the physical act of transferring a copy,
2.169 +and you may at your option offer warranty protection in exchange for a
2.170 +fee.
2.171 +
2.172 + 2. You may modify your copy or copies of the Library or any portion
2.173 +of it, thus forming a work based on the Library, and copy and
2.174 +distribute such modifications or work under the terms of Section 1
2.175 +above, provided that you also meet all of these conditions:
2.176 +
2.177 + a) The modified work must itself be a software library.
2.178 +
2.179 + b) You must cause the files modified to carry prominent notices
2.180 + stating that you changed the files and the date of any change.
2.181 +
2.182 + c) You must cause the whole of the work to be licensed at no
2.183 + charge to all third parties under the terms of this License.
2.184 +
2.185 + d) If a facility in the modified Library refers to a function or a
2.186 + table of data to be supplied by an application program that uses
2.187 + the facility, other than as an argument passed when the facility
2.188 + is invoked, then you must make a good faith effort to ensure that,
2.189 + in the event an application does not supply such function or
2.190 + table, the facility still operates, and performs whatever part of
2.191 + its purpose remains meaningful.
2.192 +
2.193 + (For example, a function in a library to compute square roots has
2.194 + a purpose that is entirely well-defined independent of the
2.195 + application. Therefore, Subsection 2d requires that any
2.196 + application-supplied function or table used by this function must
2.197 + be optional: if the application does not supply it, the square
2.198 + root function must still compute square roots.)
2.199 +
2.200 +These requirements apply to the modified work as a whole. If
2.201 +identifiable sections of that work are not derived from the Library,
2.202 +and can be reasonably considered independent and separate works in
2.203 +themselves, then this License, and its terms, do not apply to those
2.204 +sections when you distribute them as separate works. But when you
2.205 +distribute the same sections as part of a whole which is a work based
2.206 +on the Library, the distribution of the whole must be on the terms of
2.207 +this License, whose permissions for other licensees extend to the
2.208 +entire whole, and thus to each and every part regardless of who wrote
2.209 +it.
2.210 +
2.211 +Thus, it is not the intent of this section to claim rights or contest
2.212 +your rights to work written entirely by you; rather, the intent is to
2.213 +exercise the right to control the distribution of derivative or
2.214 +collective works based on the Library.
2.215 +
2.216 +In addition, mere aggregation of another work not based on the Library
2.217 +with the Library (or with a work based on the Library) on a volume of
2.218 +a storage or distribution medium does not bring the other work under
2.219 +the scope of this License.
2.220 +
2.221 + 3. You may opt to apply the terms of the ordinary GNU General Public
2.222 +License instead of this License to a given copy of the Library. To do
2.223 +this, you must alter all the notices that refer to this License, so
2.224 +that they refer to the ordinary GNU General Public License, version 2,
2.225 +instead of to this License. (If a newer version than version 2 of the
2.226 +ordinary GNU General Public License has appeared, then you can specify
2.227 +that version instead if you wish.) Do not make any other change in
2.228 +these notices.
2.229 +
2.230 + Once this change is made in a given copy, it is irreversible for
2.231 +that copy, so the ordinary GNU General Public License applies to all
2.232 +subsequent copies and derivative works made from that copy.
2.233 +
2.234 + This option is useful when you wish to copy part of the code of
2.235 +the Library into a program that is not a library.
2.236 +
2.237 + 4. You may copy and distribute the Library (or a portion or
2.238 +derivative of it, under Section 2) in object code or executable form
2.239 +under the terms of Sections 1 and 2 above provided that you accompany
2.240 +it with the complete corresponding machine-readable source code, which
2.241 +must be distributed under the terms of Sections 1 and 2 above on a
2.242 +medium customarily used for software interchange.
2.243 +
2.244 + If distribution of object code is made by offering access to copy
2.245 +from a designated place, then offering equivalent access to copy the
2.246 +source code from the same place satisfies the requirement to
2.247 +distribute the source code, even though third parties are not
2.248 +compelled to copy the source along with the object code.
2.249 +
2.250 + 5. A program that contains no derivative of any portion of the
2.251 +Library, but is designed to work with the Library by being compiled or
2.252 +linked with it, is called a "work that uses the Library". Such a
2.253 +work, in isolation, is not a derivative work of the Library, and
2.254 +therefore falls outside the scope of this License.
2.255 +
2.256 + However, linking a "work that uses the Library" with the Library
2.257 +creates an executable that is a derivative of the Library (because it
2.258 +contains portions of the Library), rather than a "work that uses the
2.259 +library". The executable is therefore covered by this License.
2.260 +Section 6 states terms for distribution of such executables.
2.261 +
2.262 + When a "work that uses the Library" uses material from a header file
2.263 +that is part of the Library, the object code for the work may be a
2.264 +derivative work of the Library even though the source code is not.
2.265 +Whether this is true is especially significant if the work can be
2.266 +linked without the Library, or if the work is itself a library. The
2.267 +threshold for this to be true is not precisely defined by law.
2.268 +
2.269 + If such an object file uses only numerical parameters, data
2.270 +structure layouts and accessors, and small macros and small inline
2.271 +functions (ten lines or less in length), then the use of the object
2.272 +file is unrestricted, regardless of whether it is legally a derivative
2.273 +work. (Executables containing this object code plus portions of the
2.274 +Library will still fall under Section 6.)
2.275 +
2.276 + Otherwise, if the work is a derivative of the Library, you may
2.277 +distribute the object code for the work under the terms of Section 6.
2.278 +Any executables containing that work also fall under Section 6,
2.279 +whether or not they are linked directly with the Library itself.
2.280 +
2.281 + 6. As an exception to the Sections above, you may also combine or
2.282 +link a "work that uses the Library" with the Library to produce a
2.283 +work containing portions of the Library, and distribute that work
2.284 +under terms of your choice, provided that the terms permit
2.285 +modification of the work for the customer's own use and reverse
2.286 +engineering for debugging such modifications.
2.287 +
2.288 + You must give prominent notice with each copy of the work that the
2.289 +Library is used in it and that the Library and its use are covered by
2.290 +this License. You must supply a copy of this License. If the work
2.291 +during execution displays copyright notices, you must include the
2.292 +copyright notice for the Library among them, as well as a reference
2.293 +directing the user to the copy of this License. Also, you must do one
2.294 +of these things:
2.295 +
2.296 + a) Accompany the work with the complete corresponding
2.297 + machine-readable source code for the Library including whatever
2.298 + changes were used in the work (which must be distributed under
2.299 + Sections 1 and 2 above); and, if the work is an executable linked
2.300 + with the Library, with the complete machine-readable "work that
2.301 + uses the Library", as object code and/or source code, so that the
2.302 + user can modify the Library and then relink to produce a modified
2.303 + executable containing the modified Library. (It is understood
2.304 + that the user who changes the contents of definitions files in the
2.305 + Library will not necessarily be able to recompile the application
2.306 + to use the modified definitions.)
2.307 +
2.308 + b) Use a suitable shared library mechanism for linking with the
2.309 + Library. A suitable mechanism is one that (1) uses at run time a
2.310 + copy of the library already present on the user's computer system,
2.311 + rather than copying library functions into the executable, and (2)
2.312 + will operate properly with a modified version of the library, if
2.313 + the user installs one, as long as the modified version is
2.314 + interface-compatible with the version that the work was made with.
2.315 +
2.316 + c) Accompany the work with a written offer, valid for at
2.317 + least three years, to give the same user the materials
2.318 + specified in Subsection 6a, above, for a charge no more
2.319 + than the cost of performing this distribution.
2.320 +
2.321 + d) If distribution of the work is made by offering access to copy
2.322 + from a designated place, offer equivalent access to copy the above
2.323 + specified materials from the same place.
2.324 +
2.325 + e) Verify that the user has already received a copy of these
2.326 + materials or that you have already sent this user a copy.
2.327 +
2.328 + For an executable, the required form of the "work that uses the
2.329 +Library" must include any data and utility programs needed for
2.330 +reproducing the executable from it. However, as a special exception,
2.331 +the materials to be distributed need not include anything that is
2.332 +normally distributed (in either source or binary form) with the major
2.333 +components (compiler, kernel, and so on) of the operating system on
2.334 +which the executable runs, unless that component itself accompanies
2.335 +the executable.
2.336 +
2.337 + It may happen that this requirement contradicts the license
2.338 +restrictions of other proprietary libraries that do not normally
2.339 +accompany the operating system. Such a contradiction means you cannot
2.340 +use both them and the Library together in an executable that you
2.341 +distribute.
2.342 +
2.343 + 7. You may place library facilities that are a work based on the
2.344 +Library side-by-side in a single library together with other library
2.345 +facilities not covered by this License, and distribute such a combined
2.346 +library, provided that the separate distribution of the work based on
2.347 +the Library and of the other library facilities is otherwise
2.348 +permitted, and provided that you do these two things:
2.349 +
2.350 + a) Accompany the combined library with a copy of the same work
2.351 + based on the Library, uncombined with any other library
2.352 + facilities. This must be distributed under the terms of the
2.353 + Sections above.
2.354 +
2.355 + b) Give prominent notice with the combined library of the fact
2.356 + that part of it is a work based on the Library, and explaining
2.357 + where to find the accompanying uncombined form of the same work.
2.358 +
2.359 + 8. You may not copy, modify, sublicense, link with, or distribute
2.360 +the Library except as expressly provided under this License. Any
2.361 +attempt otherwise to copy, modify, sublicense, link with, or
2.362 +distribute the Library is void, and will automatically terminate your
2.363 +rights under this License. However, parties who have received copies,
2.364 +or rights, from you under this License will not have their licenses
2.365 +terminated so long as such parties remain in full compliance.
2.366 +
2.367 + 9. You are not required to accept this License, since you have not
2.368 +signed it. However, nothing else grants you permission to modify or
2.369 +distribute the Library or its derivative works. These actions are
2.370 +prohibited by law if you do not accept this License. Therefore, by
2.371 +modifying or distributing the Library (or any work based on the
2.372 +Library), you indicate your acceptance of this License to do so, and
2.373 +all its terms and conditions for copying, distributing or modifying
2.374 +the Library or works based on it.
2.375 +
2.376 + 10. Each time you redistribute the Library (or any work based on the
2.377 +Library), the recipient automatically receives a license from the
2.378 +original licensor to copy, distribute, link with or modify the Library
2.379 +subject to these terms and conditions. You may not impose any further
2.380 +restrictions on the recipients' exercise of the rights granted herein.
2.381 +You are not responsible for enforcing compliance by third parties with
2.382 +this License.
2.383 +
2.384 + 11. If, as a consequence of a court judgment or allegation of patent
2.385 +infringement or for any other reason (not limited to patent issues),
2.386 +conditions are imposed on you (whether by court order, agreement or
2.387 +otherwise) that contradict the conditions of this License, they do not
2.388 +excuse you from the conditions of this License. If you cannot
2.389 +distribute so as to satisfy simultaneously your obligations under this
2.390 +License and any other pertinent obligations, then as a consequence you
2.391 +may not distribute the Library at all. For example, if a patent
2.392 +license would not permit royalty-free redistribution of the Library by
2.393 +all those who receive copies directly or indirectly through you, then
2.394 +the only way you could satisfy both it and this License would be to
2.395 +refrain entirely from distribution of the Library.
2.396 +
2.397 +If any portion of this section is held invalid or unenforceable under any
2.398 +particular circumstance, the balance of the section is intended to apply,
2.399 +and the section as a whole is intended to apply in other circumstances.
2.400 +
2.401 +It is not the purpose of this section to induce you to infringe any
2.402 +patents or other property right claims or to contest validity of any
2.403 +such claims; this section has the sole purpose of protecting the
2.404 +integrity of the free software distribution system which is
2.405 +implemented by public license practices. Many people have made
2.406 +generous contributions to the wide range of software distributed
2.407 +through that system in reliance on consistent application of that
2.408 +system; it is up to the author/donor to decide if he or she is willing
2.409 +to distribute software through any other system and a licensee cannot
2.410 +impose that choice.
2.411 +
2.412 +This section is intended to make thoroughly clear what is believed to
2.413 +be a consequence of the rest of this License.
2.414 +
2.415 + 12. If the distribution and/or use of the Library is restricted in
2.416 +certain countries either by patents or by copyrighted interfaces, the
2.417 +original copyright holder who places the Library under this License may add
2.418 +an explicit geographical distribution limitation excluding those countries,
2.419 +so that distribution is permitted only in or among countries not thus
2.420 +excluded. In such case, this License incorporates the limitation as if
2.421 +written in the body of this License.
2.422 +
2.423 + 13. The Free Software Foundation may publish revised and/or new
2.424 +versions of the Lesser General Public License from time to time.
2.425 +Such new versions will be similar in spirit to the present version,
2.426 +but may differ in detail to address new problems or concerns.
2.427 +
2.428 +Each version is given a distinguishing version number. If the Library
2.429 +specifies a version number of this License which applies to it and
2.430 +"any later version", you have the option of following the terms and
2.431 +conditions either of that version or of any later version published by
2.432 +the Free Software Foundation. If the Library does not specify a
2.433 +license version number, you may choose any version ever published by
2.434 +the Free Software Foundation.
2.435 +
2.436 + 14. If you wish to incorporate parts of the Library into other free
2.437 +programs whose distribution conditions are incompatible with these,
2.438 +write to the author to ask for permission. For software which is
2.439 +copyrighted by the Free Software Foundation, write to the Free
2.440 +Software Foundation; we sometimes make exceptions for this. Our
2.441 +decision will be guided by the two goals of preserving the free status
2.442 +of all derivatives of our free software and of promoting the sharing
2.443 +and reuse of software generally.
2.444 +
2.445 + NO WARRANTY
2.446 +
2.447 + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
2.448 +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
2.449 +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
2.450 +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
2.451 +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
2.452 +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2.453 +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
2.454 +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
2.455 +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
2.456 +
2.457 + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
2.458 +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
2.459 +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
2.460 +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
2.461 +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
2.462 +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
2.463 +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
2.464 +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
2.465 +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
2.466 +DAMAGES.
2.467 +
2.468 + END OF TERMS AND CONDITIONS
2.469 +
2.470 + How to Apply These Terms to Your New Libraries
2.471 +
2.472 + If you develop a new library, and you want it to be of the greatest
2.473 +possible use to the public, we recommend making it free software that
2.474 +everyone can redistribute and change. You can do so by permitting
2.475 +redistribution under these terms (or, alternatively, under the terms of the
2.476 +ordinary General Public License).
2.477 +
2.478 + To apply these terms, attach the following notices to the library. It is
2.479 +safest to attach them to the start of each source file to most effectively
2.480 +convey the exclusion of warranty; and each file should have at least the
2.481 +"copyright" line and a pointer to where the full notice is found.
2.482 +
2.483 + <one line to give the library's name and a brief idea of what it does.>
2.484 + Copyright (C) <year> <name of author>
2.485 +
2.486 + This library is free software; you can redistribute it and/or
2.487 + modify it under the terms of the GNU Lesser General Public
2.488 + License as published by the Free Software Foundation; either
2.489 + version 2.1 of the License, or (at your option) any later version.
2.490 +
2.491 + This library is distributed in the hope that it will be useful,
2.492 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2.493 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2.494 + Lesser General Public License for more details.
2.495 +
2.496 + You should have received a copy of the GNU Lesser General Public
2.497 + License along with this library; if not, write to the Free Software
2.498 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2.499 +
2.500 +Also add information on how to contact you by electronic and paper mail.
2.501 +
2.502 +You should also get your employer (if you work as a programmer) or your
2.503 +school, if any, to sign a "copyright disclaimer" for the library, if
2.504 +necessary. Here is a sample; alter the names:
2.505 +
2.506 + Yoyodyne, Inc., hereby disclaims all copyright interest in the
2.507 + library `Frob' (a library for tweaking knobs) written by James Random Hacker.
2.508 +
2.509 + <signature of Ty Coon>, 1 April 1990
2.510 + Ty Coon, President of Vice
3.1 --- a/docker.api/manifest.mf Wed Mar 23 21:02:01 2016 +0000
3.2 +++ b/docker.api/manifest.mf Thu Mar 24 15:34:03 2016 +0100
3.3 @@ -1,6 +1,6 @@
3.4 Manifest-Version: 1.0
3.5 OpenIDE-Module: org.netbeans.modules.docker.api/0
3.6 OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/docker/resources/Bundle.properties
3.7 -OpenIDE-Module-Specification-Version: 1.16
3.8 +OpenIDE-Module-Specification-Version: 1.19
3.9 AutoUpdate-Show-In-Client: false
3.10
4.1 --- a/docker.api/nbproject/project.properties Wed Mar 23 21:02:01 2016 +0000
4.2 +++ b/docker.api/nbproject/project.properties Thu Mar 24 15:34:03 2016 +0100
4.3 @@ -44,3 +44,5 @@
4.4 is.autoload=true
4.5 javac.compilerargs=-Xlint -Xlint:-serial
4.6 javac.source=1.8
4.7 +
4.8 +release.external/juds-0.95.jar=modules/ext/juds-0.95.jar
5.1 --- a/docker.api/nbproject/project.xml Wed Mar 23 21:02:01 2016 +0000
5.2 +++ b/docker.api/nbproject/project.xml Thu Mar 24 15:34:03 2016 +0100
5.3 @@ -94,6 +94,14 @@
5.4 </run-dependency>
5.5 </dependency>
5.6 <dependency>
5.7 + <code-name-base>org.openide.modules</code-name-base>
5.8 + <build-prerequisite/>
5.9 + <compile-dependency/>
5.10 + <run-dependency>
5.11 + <specification-version>7.48</specification-version>
5.12 + </run-dependency>
5.13 + </dependency>
5.14 + <dependency>
5.15 <code-name-base>org.openide.util</code-name-base>
5.16 <build-prerequisite/>
5.17 <compile-dependency/>
5.18 @@ -138,6 +146,10 @@
5.19 <friend>org.netbeans.modules.docker.ui</friend>
5.20 <package>org.netbeans.modules.docker.api</package>
5.21 </friend-packages>
5.22 + <class-path-extension>
5.23 + <runtime-relative-path>ext/juds-0.95.jar</runtime-relative-path>
5.24 + <binary-origin>external/juds-0.95.jar</binary-origin>
5.25 + </class-path-extension>
5.26 </data>
5.27 </configuration>
5.28 </project>
6.1 --- a/docker.api/src/org/netbeans/modules/docker/ConnectionListener.java Wed Mar 23 21:02:01 2016 +0000
6.2 +++ b/docker.api/src/org/netbeans/modules/docker/ConnectionListener.java Thu Mar 24 15:34:03 2016 +0100
6.3 @@ -41,15 +41,13 @@
6.4 */
6.5 package org.netbeans.modules.docker;
6.6
6.7 -import java.net.Socket;
6.8 -
6.9 /**
6.10 *
6.11 * @author Petr Hejl
6.12 */
6.13 public interface ConnectionListener {
6.14
6.15 - void onConnect(Socket s);
6.16 + void onConnect(Endpoint e);
6.17
6.18 void onDisconnect();
6.19
7.1 --- a/docker.api/src/org/netbeans/modules/docker/DirectStreamResult.java Wed Mar 23 21:02:01 2016 +0000
7.2 +++ b/docker.api/src/org/netbeans/modules/docker/DirectStreamResult.java Thu Mar 24 15:34:03 2016 +0100
7.3 @@ -53,7 +53,7 @@
7.4 */
7.5 public class DirectStreamResult implements StreamResult {
7.6
7.7 - private final Socket s;
7.8 + private final Endpoint s;
7.9
7.10 private final Charset charset;
7.11
7.12 @@ -63,7 +63,7 @@
7.13
7.14 private final InputStream stdErr;
7.15
7.16 - public DirectStreamResult(Socket s, Charset charset, InputStream is) throws IOException {
7.17 + public DirectStreamResult(Endpoint s, Charset charset, InputStream is) throws IOException {
7.18 this.s = s;
7.19 this.charset = charset;
7.20 this.stdIn = s.getOutputStream();
8.1 --- a/docker.api/src/org/netbeans/modules/docker/DockerEventBus.java Wed Mar 23 21:02:01 2016 +0000
8.2 +++ b/docker.api/src/org/netbeans/modules/docker/DockerEventBus.java Thu Mar 24 15:34:03 2016 +0100
8.3 @@ -43,7 +43,6 @@
8.4
8.5 import java.io.Closeable;
8.6 import java.io.IOException;
8.7 -import java.net.Socket;
8.8 import java.util.ArrayList;
8.9 import java.util.List;
8.10 import java.util.logging.Level;
8.11 @@ -76,7 +75,7 @@
8.12
8.13 private final List<DockerEvent.Listener> containerListeners = new ArrayList<>();
8.14
8.15 - private Socket socket;
8.16 + private Endpoint endpoint;
8.17
8.18 private DockerEvent lastEvent;
8.19
8.20 @@ -173,10 +172,10 @@
8.21 }
8.22
8.23 @Override
8.24 - public void onConnect(Socket s) {
8.25 + public void onConnect(Endpoint e) {
8.26 List<DockerInstance.ConnectionListener> toFire;
8.27 synchronized (this) {
8.28 - this.socket = s;
8.29 + this.endpoint = e;
8.30 toFire = new ArrayList<>(connectionListeners);
8.31 }
8.32 for (DockerInstance.ConnectionListener l : toFire) {
8.33 @@ -258,11 +257,11 @@
8.34
8.35 private void stop() {
8.36 // FIXME close the socket to stop waiting for events
8.37 - Socket current;
8.38 + Endpoint current;
8.39 synchronized (this) {
8.40 stop = true;
8.41 - current = socket;
8.42 - socket = null;
8.43 + current = endpoint;
8.44 + endpoint = null;
8.45 }
8.46 try {
8.47 if (current != null) {
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/docker.api/src/org/netbeans/modules/docker/Endpoint.java Thu Mar 24 15:34:03 2016 +0100
9.3 @@ -0,0 +1,98 @@
9.4 +/*
9.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
9.6 + *
9.7 + * Copyright 2016 Oracle and/or its affiliates. All rights reserved.
9.8 + *
9.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
9.10 + * Other names may be trademarks of their respective owners.
9.11 + *
9.12 + * The contents of this file are subject to the terms of either the GNU
9.13 + * General Public License Version 2 only ("GPL") or the Common
9.14 + * Development and Distribution License("CDDL") (collectively, the
9.15 + * "License"). You may not use this file except in compliance with the
9.16 + * License. You can obtain a copy of the License at
9.17 + * http://www.netbeans.org/cddl-gplv2.html
9.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
9.19 + * specific language governing permissions and limitations under the
9.20 + * License. When distributing the software, include this License Header
9.21 + * Notice in each file and include the License file at
9.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
9.23 + * particular file as subject to the "Classpath" exception as provided
9.24 + * by Oracle in the GPL Version 2 section of the License file that
9.25 + * accompanied this code. If applicable, add the following below the
9.26 + * License Header, with the fields enclosed by brackets [] replaced by
9.27 + * your own identifying information:
9.28 + * "Portions Copyrighted [year] [name of copyright owner]"
9.29 + *
9.30 + * If you wish your version of this file to be governed by only the CDDL
9.31 + * or only the GPL Version 2, indicate your decision by adding
9.32 + * "[Contributor] elects to include this software in this distribution
9.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
9.34 + * single choice of license, a recipient has the option to distribute
9.35 + * your version of this file under either the CDDL, the GPL Version 2 or
9.36 + * to extend the choice of license to its licensees as provided above.
9.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
9.38 + * Version 2 license, then the option applies only if the new code is
9.39 + * made subject to such option by the copyright holder.
9.40 + *
9.41 + * Contributor(s):
9.42 + *
9.43 + * Portions Copyrighted 2016 Sun Microsystems, Inc.
9.44 + */
9.45 +package org.netbeans.modules.docker;
9.46 +
9.47 +import com.etsy.net.UnixDomainSocketClient;
9.48 +import java.io.Closeable;
9.49 +import java.io.IOException;
9.50 +import java.io.InputStream;
9.51 +import java.io.OutputStream;
9.52 +import java.net.Socket;
9.53 +
9.54 +/**
9.55 + *
9.56 + * @author Petr Hejl
9.57 + */
9.58 +public interface Endpoint extends Closeable {
9.59 +
9.60 + InputStream getInputStream() throws IOException;
9.61 +
9.62 + OutputStream getOutputStream() throws IOException;
9.63 +
9.64 + public static Endpoint forSocket(final Socket s) {
9.65 + return new Endpoint() {
9.66 + @Override
9.67 + public InputStream getInputStream() throws IOException {
9.68 + return s.getInputStream();
9.69 + }
9.70 +
9.71 + @Override
9.72 + public OutputStream getOutputStream() throws IOException {
9.73 + return s.getOutputStream();
9.74 + }
9.75 +
9.76 + @Override
9.77 + public void close() throws IOException {
9.78 + s.close();
9.79 + }
9.80 + };
9.81 + }
9.82 +
9.83 + public static Endpoint forDomainSocket(final UnixDomainSocketClient s) {
9.84 + return new Endpoint() {
9.85 + @Override
9.86 + public InputStream getInputStream() throws IOException {
9.87 + return s.getInputStream();
9.88 + }
9.89 +
9.90 + @Override
9.91 + public OutputStream getOutputStream() throws IOException {
9.92 + return s.getOutputStream();
9.93 + }
9.94 +
9.95 + @Override
9.96 + public void close() throws IOException {
9.97 + s.close();
9.98 + }
9.99 + };
9.100 + }
9.101 +}
10.1 --- a/docker.api/src/org/netbeans/modules/docker/HttpUtils.java Wed Mar 23 21:02:01 2016 +0000
10.2 +++ b/docker.api/src/org/netbeans/modules/docker/HttpUtils.java Thu Mar 24 15:34:03 2016 +0100
10.3 @@ -43,11 +43,11 @@
10.4
10.5 import java.io.BufferedInputStream;
10.6 import java.io.ByteArrayOutputStream;
10.7 +import java.io.FilterInputStream;
10.8 import java.io.IOException;
10.9 import java.io.InputStream;
10.10 import java.io.OutputStream;
10.11 import java.io.UnsupportedEncodingException;
10.12 -import java.net.HttpURLConnection;
10.13 import java.net.URLEncoder;
10.14 import java.nio.charset.Charset;
10.15 import java.nio.charset.UnsupportedCharsetException;
10.16 @@ -58,6 +58,7 @@
10.17 import java.util.regex.Matcher;
10.18 import java.util.regex.Pattern;
10.19 import org.netbeans.api.annotations.common.CheckForNull;
10.20 +import org.netbeans.api.annotations.common.NonNull;
10.21 import org.openide.util.Pair;
10.22
10.23 /**
10.24 @@ -107,26 +108,45 @@
10.25 return new String(content, encoding);
10.26 }
10.27
10.28 - public static String readError(HttpURLConnection conn) throws IOException {
10.29 - InputStream err = conn.getErrorStream();
10.30 - if (err == null || err.available() <= 0) {
10.31 - return null;
10.32 - }
10.33 - Charset encoding = getCharset(conn.getContentType());
10.34 - ByteArrayOutputStream bos = new ByteArrayOutputStream(200);
10.35 - byte[] content = new byte[200];
10.36 - int length;
10.37 - while((length = err.read(content)) != -1) {
10.38 - bos.write(content, 0, length);
10.39 - }
10.40 - return bos.toString(encoding.name());
10.41 - }
10.42 -
10.43 - public static InputStream getResponseStream(InputStream is, Response response) {
10.44 + public static InputStream getResponseStream(InputStream is, Response response, boolean allowSocketStream) throws IOException {
10.45 if (isChunked(response.getHeaders())) {
10.46 return new ChunkedInputStream(new BufferedInputStream(is));
10.47 } else {
10.48 - return new BufferedInputStream(is);
10.49 + Integer l = getLength(response.getHeaders());
10.50 + if (l != null) {
10.51 + return new BufferedInputStream(new FilterInputStream(is) {
10.52 + private int available = l;
10.53 +
10.54 + @Override
10.55 + public int available() throws IOException {
10.56 + return Math.min(super.available(), available);
10.57 + }
10.58 +
10.59 + @Override
10.60 + public int read(byte[] b, int off, int len) throws IOException {
10.61 + if (available <= 0) {
10.62 + return -1;
10.63 + }
10.64 + int real = Math.min(available, len);
10.65 + int count = super.read(b, off, real);
10.66 + available -= count;
10.67 + return count;
10.68 + }
10.69 +
10.70 + @Override
10.71 + public int read() throws IOException {
10.72 + if (available <= 0) {
10.73 + return -1;
10.74 + }
10.75 + available--;
10.76 + return super.read();
10.77 + }
10.78 + });
10.79 + } else if (allowSocketStream) {
10.80 + return new BufferedInputStream(is);
10.81 + } else {
10.82 + throw new IOException("Undefined content length");
10.83 + }
10.84 }
10.85 }
10.86
10.87 @@ -142,14 +162,11 @@
10.88 }
10.89 }
10.90
10.91 + @NonNull
10.92 public static Charset getCharset(Response response) {
10.93 return getCharset(response.getHeaders().get("CONTENT-TYPE")); // NOI18N
10.94 }
10.95
10.96 - public static Charset getCharset(HttpURLConnection connection) {
10.97 - return getCharset(connection.getContentType());
10.98 - }
10.99 -
10.100 public static String encodeParameter(String value) throws UnsupportedEncodingException {
10.101 return URLEncoder.encode(value, "UTF-8");
10.102 }
10.103 @@ -181,20 +198,6 @@
10.104 }
10.105 }
10.106
10.107 - public static void configureHeaders(HttpURLConnection conn, Map<String, String> defaultHeaders,
10.108 - Pair<String, String>... headers) {
10.109 -
10.110 - for (Map.Entry<String, String> e : defaultHeaders.entrySet()) {
10.111 - conn.setRequestProperty(e.getKey(), e.getValue());
10.112 - }
10.113 - for (Pair<String, String> h : headers) {
10.114 - if (h == null) {
10.115 - continue;
10.116 - }
10.117 - conn.setRequestProperty(h.first(), h.second());
10.118 - }
10.119 - }
10.120 -
10.121 static String readResponseLine(InputStream is) throws IOException {
10.122 ByteArrayOutputStream bos = new ByteArrayOutputStream();
10.123 int b;
11.1 --- a/docker.api/src/org/netbeans/modules/docker/MuxedStreamResult.java Wed Mar 23 21:02:01 2016 +0000
11.2 +++ b/docker.api/src/org/netbeans/modules/docker/MuxedStreamResult.java Thu Mar 24 15:34:03 2016 +0100
11.3 @@ -57,7 +57,7 @@
11.4
11.5 private static final Logger LOGGER = Logger.getLogger(MuxedStreamResult.class.getName());
11.6
11.7 - private final Socket s;
11.8 + private final Endpoint s;
11.9
11.10 private final Charset charset;
11.11
11.12 @@ -71,7 +71,7 @@
11.13
11.14 private StreamItem last = StreamItem.EMPTY;
11.15
11.16 - public MuxedStreamResult(Socket s, Charset charset, InputStream is) throws IOException {
11.17 + public MuxedStreamResult(Endpoint s, Charset charset, InputStream is) throws IOException {
11.18 this.s = s;
11.19 this.charset = charset;
11.20 this.outputStream = s.getOutputStream();
12.1 --- a/docker.api/src/org/netbeans/modules/docker/api/ActionChunkedResult.java Wed Mar 23 21:02:01 2016 +0000
12.2 +++ b/docker.api/src/org/netbeans/modules/docker/api/ActionChunkedResult.java Thu Mar 24 15:34:03 2016 +0100
12.3 @@ -43,10 +43,10 @@
12.4
12.5 import java.io.Closeable;
12.6 import java.io.IOException;
12.7 -import java.net.Socket;
12.8 import java.nio.ByteBuffer;
12.9 import java.nio.charset.Charset;
12.10 import org.netbeans.api.annotations.common.CheckForNull;
12.11 +import org.netbeans.modules.docker.Endpoint;
12.12 import org.netbeans.modules.docker.StreamItem;
12.13
12.14 /**
12.15 @@ -55,13 +55,13 @@
12.16 */
12.17 public final class ActionChunkedResult implements Closeable {
12.18
12.19 - private final Socket s;
12.20 + private final Endpoint s;
12.21
12.22 private final StreamItem.Fetcher fetcher;
12.23
12.24 private final Charset charset;
12.25
12.26 - ActionChunkedResult(Socket s, StreamItem.Fetcher fetcher, Charset charset) {
12.27 + ActionChunkedResult(Endpoint s, StreamItem.Fetcher fetcher, Charset charset) {
12.28 this.s = s;
12.29 this.fetcher = fetcher;
12.30 this.charset = charset;
13.1 --- a/docker.api/src/org/netbeans/modules/docker/api/DockerAction.java Wed Mar 23 21:02:01 2016 +0000
13.2 +++ b/docker.api/src/org/netbeans/modules/docker/api/DockerAction.java Thu Mar 24 15:34:03 2016 +0100
13.3 @@ -41,6 +41,8 @@
13.4 */
13.5 package org.netbeans.modules.docker.api;
13.6
13.7 +import com.etsy.net.JUDS;
13.8 +import com.etsy.net.UnixDomainSocketClient;
13.9 import org.netbeans.modules.docker.StreamItem;
13.10 import org.netbeans.modules.docker.ConnectionListener;
13.11 import org.netbeans.modules.docker.DockerRemoteException;
13.12 @@ -52,7 +54,6 @@
13.13 import org.netbeans.modules.docker.HttpUtils;
13.14 import org.netbeans.modules.docker.DirectStreamResult;
13.15 import org.netbeans.modules.docker.Demuxer;
13.16 -import java.io.BufferedOutputStream;
13.17 import java.io.BufferedReader;
13.18 import java.io.File;
13.19 import java.io.IOException;
13.20 @@ -87,7 +88,6 @@
13.21 import java.util.logging.Logger;
13.22 import java.util.regex.Matcher;
13.23 import java.util.regex.Pattern;
13.24 -import javax.net.ssl.HttpsURLConnection;
13.25 import javax.net.ssl.SSLContext;
13.26 import javax.swing.SwingUtilities;
13.27 import org.json.simple.JSONArray;
13.28 @@ -99,11 +99,10 @@
13.29 import org.netbeans.modules.docker.DockerActionAccessor;
13.30 import org.netbeans.modules.docker.DockerConfig;
13.31 import org.netbeans.modules.docker.DockerUtils;
13.32 +import org.netbeans.modules.docker.Endpoint;
13.33 import org.netbeans.modules.docker.StreamResult;
13.34 -import org.openide.filesystems.FileUtil;
13.35 import org.openide.util.Pair;
13.36 import org.openide.util.Parameters;
13.37 -import org.openide.util.RequestProcessor;
13.38 import org.openide.util.io.NullInputStream;
13.39 import org.openide.util.io.NullOutputStream;
13.40
13.41 @@ -130,6 +129,11 @@
13.42 private static final Pair<String, String> ACCEPT_JSON_HEADER = Pair.of("Accept", "application/json");
13.43
13.44 static {
13.45 + if (System.getProperty("juds.folder.preferred") == null) {
13.46 + String userhome = System.getProperty("netbeans.user");
13.47 + System.setProperty("juds.folder.preferred", userhome);
13.48 + }
13.49 +
13.50 DockerActionAccessor.setDefault(new DockerActionAccessor() {
13.51 @Override
13.52 public void events(DockerAction action, Long since, DockerEvent.Listener listener, ConnectionListener connectionListener) throws DockerException {
13.53 @@ -142,8 +146,6 @@
13.54 Collections.addAll(REMOVE_IMAGE_CODES, HttpURLConnection.HTTP_OK, HttpURLConnection.HTTP_NOT_FOUND);
13.55 }
13.56
13.57 - private final RequestProcessor requestProcessor = new RequestProcessor(DockerAction.class);
13.58 -
13.59 private final DockerInstance instance;
13.60
13.61 private final boolean emitEvents;
13.62 @@ -160,8 +162,8 @@
13.63
13.64 public List<DockerImage> getImages() {
13.65 try {
13.66 - JSONArray value = (JSONArray) doGetRequest(instance.getUrl(),
13.67 - "/images/json", Collections.singleton(HttpURLConnection.HTTP_OK));
13.68 + JSONArray value = (JSONArray) doGetRequest("/images/json",
13.69 + Collections.singleton(HttpURLConnection.HTTP_OK));
13.70 List<DockerImage> ret = new ArrayList<>(value.size());
13.71 for (Object o : value) {
13.72 JSONObject json = (JSONObject) o;
13.73 @@ -181,8 +183,8 @@
13.74
13.75 public List<DockerContainer> getContainers() {
13.76 try {
13.77 - JSONArray value = (JSONArray) doGetRequest(instance.getUrl(),
13.78 - "/containers/json?all=1", Collections.singleton(HttpURLConnection.HTTP_OK));
13.79 + JSONArray value = (JSONArray) doGetRequest("/containers/json?all=1",
13.80 + Collections.singleton(HttpURLConnection.HTTP_OK));
13.81 List<DockerContainer> ret = new ArrayList<>(value.size());
13.82 for (Object o : value) {
13.83 JSONObject json = (JSONObject) o;
13.84 @@ -210,8 +212,9 @@
13.85 }
13.86
13.87 try {
13.88 - JSONArray value = (JSONArray) doGetRequest(instance.getUrl(),
13.89 - "/images/search?term=" + HttpUtils.encodeParameter(searchTerm), Collections.singleton(HttpURLConnection.HTTP_OK));
13.90 + JSONArray value = (JSONArray) doGetRequest(
13.91 + "/images/search?term=" + HttpUtils.encodeParameter(searchTerm),
13.92 + Collections.singleton(HttpURLConnection.HTTP_OK));
13.93 List<DockerRegistryImage> ret = new ArrayList<>(value.size());
13.94 for (Object o : value) {
13.95 JSONObject json = (JSONObject) o;
13.96 @@ -256,7 +259,7 @@
13.97 action.append("&pause=0");
13.98 }
13.99
13.100 - JSONObject value = (JSONObject) doPostRequest(instance.getUrl(), action.toString(), null,
13.101 + JSONObject value = (JSONObject) doPostRequest(action.toString(),
13.102 true, Collections.singleton(HttpURLConnection.HTTP_CREATED));
13.103
13.104 String id = (String) value.get("Id");
13.105 @@ -282,8 +285,7 @@
13.106 Parameters.notNull("name", name);
13.107
13.108 try {
13.109 - doPostRequest(instance.getUrl(),
13.110 - "/containers/" + container.getId() + "/rename?name=" + HttpUtils.encodeParameter(name), null,
13.111 + doPostRequest("/containers/" + container.getId() + "/rename?name=" + HttpUtils.encodeParameter(name),
13.112 false, Collections.singleton(HttpURLConnection.HTTP_NO_CONTENT));
13.113
13.114 long time = System.currentTimeMillis() / 1000;
13.115 @@ -315,7 +317,7 @@
13.116 action.append("&tag=").append(tag);
13.117 }
13.118
13.119 - doPostRequest(instance.getUrl(), action.toString(), null,
13.120 + doPostRequest(action.toString(),
13.121 false, Collections.singleton(HttpURLConnection.HTTP_CREATED));
13.122
13.123 String tagResult = DockerUtils.getTag(repository, tag);
13.124 @@ -331,8 +333,8 @@
13.125 }
13.126
13.127 public DockerContainerDetail getDetail(DockerContainer container) throws DockerException {
13.128 - JSONObject value = (JSONObject) doGetRequest(instance.getUrl(),
13.129 - "/containers/" + container.getId() + "/json", Collections.singleton(HttpURLConnection.HTTP_OK));
13.130 + JSONObject value = (JSONObject) doGetRequest("/containers/" + container.getId() + "/json",
13.131 + Collections.singleton(HttpURLConnection.HTTP_OK));
13.132 String name = (String) value.get("Name");
13.133 DockerContainer.Status status = DockerContainer.Status.STOPPED;
13.134 JSONObject state = (JSONObject) value.get("State");
13.135 @@ -359,8 +361,8 @@
13.136 }
13.137
13.138 public DockerImageDetail getDetail(DockerImage image) throws DockerException {
13.139 - JSONObject value = (JSONObject) doGetRequest(instance.getUrl(),
13.140 - "/images/" + image.getId() + "/json", Collections.singleton(HttpURLConnection.HTTP_OK));
13.141 + JSONObject value = (JSONObject) doGetRequest("/images/" + image.getId() + "/json",
13.142 + Collections.singleton(HttpURLConnection.HTTP_OK));
13.143 List<ExposedPort> ports = new LinkedList<>();
13.144 JSONObject config = (JSONObject) value.get("Config");
13.145 if (config != null) {
13.146 @@ -383,7 +385,7 @@
13.147 }
13.148
13.149 public void start(DockerContainer container) throws DockerException {
13.150 - doPostRequest(instance.getUrl(), "/containers/" + container.getId() + "/start", null, false, START_STOP_CONTAINER_CODES);
13.151 + doPostRequest("/containers/" + container.getId() + "/start", false, START_STOP_CONTAINER_CODES);
13.152
13.153 if (emitEvents) {
13.154 instance.getEventBus().sendEvent(
13.155 @@ -393,7 +395,7 @@
13.156 }
13.157
13.158 public void stop(DockerContainer container) throws DockerException {
13.159 - doPostRequest(instance.getUrl(), "/containers/" + container.getId() + "/stop", null, false, START_STOP_CONTAINER_CODES);
13.160 + doPostRequest("/containers/" + container.getId() + "/stop", false, START_STOP_CONTAINER_CODES);
13.161
13.162 if (emitEvents) {
13.163 instance.getEventBus().sendEvent(
13.164 @@ -403,7 +405,7 @@
13.165 }
13.166
13.167 public void pause(DockerContainer container) throws DockerException {
13.168 - doPostRequest(instance.getUrl(), "/containers/" + container.getId() + "/pause", null, false,
13.169 + doPostRequest("/containers/" + container.getId() + "/pause", false,
13.170 Collections.singleton(HttpURLConnection.HTTP_NO_CONTENT));
13.171
13.172 if (emitEvents) {
13.173 @@ -414,7 +416,7 @@
13.174 }
13.175
13.176 public void unpause(DockerContainer container) throws DockerException {
13.177 - doPostRequest(instance.getUrl(), "/containers/" + container.getId() + "/unpause", null, false,
13.178 + doPostRequest("/containers/" + container.getId() + "/unpause", false,
13.179 Collections.singleton(HttpURLConnection.HTTP_NO_CONTENT));
13.180
13.181 if (emitEvents) {
13.182 @@ -426,7 +428,7 @@
13.183
13.184 public void remove(DockerTag tag) throws DockerException {
13.185 String id = getImage(tag);
13.186 - doDeleteRequest(instance.getUrl(), "/images/" + id, true, REMOVE_IMAGE_CODES);
13.187 + doDeleteRequest("/images/" + id, true, REMOVE_IMAGE_CODES);
13.188
13.189 // XXX to be precise we should emit DELETE event if we
13.190 // delete the last image, but for our purpose this is enough
13.191 @@ -438,7 +440,7 @@
13.192 }
13.193
13.194 public void remove(DockerContainer container) throws DockerException {
13.195 - doDeleteRequest(instance.getUrl(), "/containers/" + container.getId(), false,
13.196 + doDeleteRequest("/containers/" + container.getId(), false,
13.197 REMOVE_CONTAINER_CODES);
13.198
13.199 if (emitEvents) {
13.200 @@ -450,8 +452,8 @@
13.201
13.202 public void resizeTerminal(DockerContainer container, int rows, int columns) throws DockerException {
13.203 // formally there should be restart so changes take place
13.204 - doPostRequest(instance.getUrl(), "/containers/" + container.getId() + "/resize?h=" + rows + "&w=" + columns,
13.205 - null, false, Collections.singleton(HttpURLConnection.HTTP_OK));
13.206 + doPostRequest("/containers/" + container.getId() + "/resize?h=" + rows + "&w=" + columns,
13.207 + false, Collections.singleton(HttpURLConnection.HTTP_OK));
13.208 }
13.209
13.210 // this call is BLOCKING
13.211 @@ -459,10 +461,9 @@
13.212 assert !SwingUtilities.isEventDispatchThread() : "Remote access invoked from EDT";
13.213
13.214 DockerContainerDetail info = DockerAction.this.getDetail(container);
13.215 - Socket s = null;
13.216 + Endpoint s = null;
13.217 try {
13.218 - URL url = createURL(instance.getUrl(), null);
13.219 - s = createSocket(url);
13.220 + s = createEndpoint();
13.221
13.222 OutputStream os = s.getOutputStream();
13.223 os.write(("POST /containers/" + container.getId()
13.224 @@ -492,10 +493,10 @@
13.225 Charset ch = HttpUtils.getCharset(response);
13.226 Integer length = HttpUtils.getLength(response.getHeaders());
13.227 if (length != null && length <= 0) {
13.228 - closeSocket(s);
13.229 + closeEndpoint(s);
13.230 return new ActionStreamResult(new EmptyStreamResult(info.isTty()));
13.231 }
13.232 - is = HttpUtils.getResponseStream(is, response);
13.233 + is = HttpUtils.getResponseStream(is, response, true);
13.234
13.235 if (info.isTty()) {
13.236 return new ActionStreamResult(new DirectStreamResult(s, ch, is));
13.237 @@ -503,13 +504,13 @@
13.238 return new ActionStreamResult(new MuxedStreamResult(s, ch, is));
13.239 }
13.240 } catch (MalformedURLException e) {
13.241 - closeSocket(s);
13.242 + closeEndpoint(s);
13.243 throw new DockerException(e);
13.244 } catch (IOException e) {
13.245 - closeSocket(s);
13.246 + closeEndpoint(s);
13.247 throw new DockerException(e);
13.248 } catch (DockerException e) {
13.249 - closeSocket(s);
13.250 + closeEndpoint(s);
13.251 throw e;
13.252 }
13.253 }
13.254 @@ -520,26 +521,34 @@
13.255
13.256 try {
13.257 DockerName parsed = DockerName.parse(imageName);
13.258 - URL httpUrl = createURL(instance.getUrl(), "/images/create?fromImage="
13.259 - + HttpUtils.encodeParameter(imageName));
13.260 - HttpURLConnection conn = createConnection(httpUrl);
13.261 + Endpoint s = createEndpoint();
13.262 try {
13.263 - conn.setRequestMethod("POST");
13.264 + OutputStream os = s.getOutputStream();
13.265 + os.write(("POST /images/create?fromImage="
13.266 + + HttpUtils.encodeParameter(imageName) + " HTTP/1.1\r\n").getBytes("ISO-8859-1"));
13.267 Pair<String, String> authHeader = null;
13.268 JSONObject auth = createAuthObject(CredentialsManager.getDefault().getCredentials(parsed.getRegistry()));
13.269 authHeader = Pair.of("X-Registry-Auth", HttpUtils.encodeBase64(auth.toJSONString()));
13.270 - HttpUtils.configureHeaders(conn, DockerConfig.getDefault().getHttpHeaders(),
13.271 + HttpUtils.configureHeaders(os, DockerConfig.getDefault().getHttpHeaders(),
13.272 ACCEPT_JSON_HEADER, authHeader);
13.273 + os.write(("\r\n").getBytes("ISO-8859-1"));
13.274 + os.flush();
13.275
13.276 - if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
13.277 - String error = HttpUtils.readError(conn);
13.278 - throw codeToException(conn.getResponseCode(),
13.279 - error != null ? error : conn.getResponseMessage());
13.280 + InputStream is = s.getInputStream();
13.281 + HttpUtils.Response response = HttpUtils.readResponse(is);
13.282 + int responseCode = response.getCode();
13.283 +
13.284 + is = HttpUtils.getResponseStream(is, response, false);
13.285 +
13.286 + if (responseCode != HttpURLConnection.HTTP_OK) {
13.287 + String error = HttpUtils.readContent(is, response);
13.288 + throw codeToException(responseCode,
13.289 + error != null ? error : response.getMessage());
13.290 }
13.291
13.292 String authFailure = null;
13.293 JSONParser parser = new JSONParser();
13.294 - try (InputStreamReader r = new InputStreamReader(conn.getInputStream(), HttpUtils.getCharset(conn))) {
13.295 + try (InputStreamReader r = new InputStreamReader(is, HttpUtils.getCharset(response))) {
13.296 String line;
13.297 while ((line = readEventObject(r)) != null) {
13.298 JSONObject o = (JSONObject) parser.parse(line);
13.299 @@ -560,7 +569,7 @@
13.300 throw new DockerAuthenticationException(authFailure);
13.301 }
13.302 } finally {
13.303 - conn.disconnect();
13.304 + closeEndpoint(s);
13.305 }
13.306 } catch (MalformedURLException e) {
13.307 throw new DockerException(e);
13.308 @@ -589,25 +598,33 @@
13.309 action.append("?tag=").append(HttpUtils.encodeParameter(tagString));
13.310 }
13.311
13.312 - URL httpUrl = createURL(instance.getUrl(), action.toString());
13.313 - HttpURLConnection conn = createConnection(httpUrl);
13.314 + Endpoint s = createEndpoint();
13.315 try {
13.316 - conn.setRequestMethod("POST");
13.317 + OutputStream os = s.getOutputStream();
13.318 + os.write(("POST " + action.toString() + " HTTP/1.1\r\n").getBytes("ISO-8859-1"));
13.319 Pair<String, String> authHeader = null;
13.320 JSONObject auth = createAuthObject(CredentialsManager.getDefault().getCredentials(parsed.getRegistry()));
13.321 authHeader = Pair.of("X-Registry-Auth", HttpUtils.encodeBase64(auth.toJSONString()));
13.322 - HttpUtils.configureHeaders(conn, DockerConfig.getDefault().getHttpHeaders(),
13.323 + HttpUtils.configureHeaders(os, DockerConfig.getDefault().getHttpHeaders(),
13.324 ACCEPT_JSON_HEADER, authHeader);
13.325 + os.write(("\r\n").getBytes("ISO-8859-1"));
13.326 + os.flush();
13.327
13.328 - if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
13.329 - String error = HttpUtils.readError(conn);
13.330 - throw codeToException(conn.getResponseCode(),
13.331 - error != null ? error : conn.getResponseMessage());
13.332 + InputStream is = s.getInputStream();
13.333 + HttpUtils.Response response = HttpUtils.readResponse(is);
13.334 + int responseCode = response.getCode();
13.335 +
13.336 + is = HttpUtils.getResponseStream(is, response, false);
13.337 +
13.338 + if (responseCode != HttpURLConnection.HTTP_OK) {
13.339 + String error = HttpUtils.readContent(is, response);
13.340 + throw codeToException(responseCode,
13.341 + error != null ? error : response.getMessage());
13.342 }
13.343
13.344 String authFailure = null;
13.345 JSONParser parser = new JSONParser();
13.346 - try (InputStreamReader r = new InputStreamReader(conn.getInputStream(), HttpUtils.getCharset(conn))) {
13.347 + try (InputStreamReader r = new InputStreamReader(is, HttpUtils.getCharset(response))) {
13.348 String line;
13.349 while ((line = readEventObject(r)) != null) {
13.350 JSONObject o = (JSONObject) parser.parse(line);
13.351 @@ -628,7 +645,7 @@
13.352 throw new DockerAuthenticationException(authFailure);
13.353 }
13.354 } finally {
13.355 - conn.disconnect();
13.356 + closeEndpoint(s);
13.357 }
13.358 } catch (MalformedURLException e) {
13.359 throw new DockerException(e);
13.360 @@ -663,15 +680,14 @@
13.361 dockerfileName = dockerfile.getName();
13.362 }
13.363
13.364 - Socket s = null;
13.365 + Endpoint s = null;
13.366 try {
13.367 - URL url = createURL(instance.getUrl(), null);
13.368 - s = createSocket(url);
13.369 + s = createEndpoint();
13.370 synchronized (handler) {
13.371 if (handler.isCancelled()) {
13.372 return null;
13.373 }
13.374 - handler.setSocket(s);
13.375 + handler.setEndpoint(s);
13.376 }
13.377
13.378 StringBuilder request = new StringBuilder();
13.379 @@ -746,7 +762,7 @@
13.380 throw new DockerException(ex.getCause());
13.381 }
13.382
13.383 - is = HttpUtils.getResponseStream(is, response);
13.384 + is = HttpUtils.getResponseStream(is, response, false);
13.385
13.386 JSONParser parser = new JSONParser();
13.387 try (InputStreamReader r = new InputStreamReader(is, HttpUtils.getCharset(response))) {
13.388 @@ -802,16 +818,16 @@
13.389 }
13.390 return null;
13.391 } catch (MalformedURLException e) {
13.392 - closeSocket(s);
13.393 + closeEndpoint(s);
13.394 throw new DockerException(e);
13.395 } catch (IOException e) {
13.396 - closeSocket(s);
13.397 + closeEndpoint(s);
13.398 if (!handler.isCancelled()) {
13.399 throw new DockerException(e);
13.400 }
13.401 return null;
13.402 } catch (DockerException e) {
13.403 - closeSocket(s);
13.404 + closeEndpoint(s);
13.405 throw e;
13.406 }
13.407 }
13.408 @@ -835,10 +851,9 @@
13.409 assert !SwingUtilities.isEventDispatchThread() : "Remote access invoked from EDT";
13.410
13.411 DockerContainerDetail info = getDetail(container);
13.412 - Socket s = null;
13.413 + Endpoint s = null;
13.414 try {
13.415 - URL url = createURL(instance.getUrl(), null);
13.416 - s = createSocket(url);
13.417 + s = createEndpoint();
13.418
13.419 OutputStream os = s.getOutputStream();
13.420 os.write(("GET /containers/" + container.getId() + "/logs?stderr=1&stdout=1×tamps=1&follow=1 HTTP/1.1\r\n").getBytes("ISO-8859-1"));
13.421 @@ -855,7 +870,7 @@
13.422 error != null ? error : response.getMessage());
13.423 }
13.424
13.425 - is = HttpUtils.getResponseStream(is, response);
13.426 + is = HttpUtils.getResponseStream(is, response, true);
13.427
13.428 StreamItem.Fetcher fetcher;
13.429 Integer length = HttpUtils.getLength(response.getHeaders());
13.430 @@ -876,23 +891,22 @@
13.431 }
13.432 return new ActionChunkedResult(s, fetcher, HttpUtils.getCharset(response));
13.433 } catch (MalformedURLException e) {
13.434 - closeSocket(s);
13.435 + closeEndpoint(s);
13.436 throw new DockerException(e);
13.437 } catch (IOException e) {
13.438 - closeSocket(s);
13.439 + closeEndpoint(s);
13.440 throw new DockerException(e);
13.441 } catch (DockerException e) {
13.442 - closeSocket(s);
13.443 + closeEndpoint(s);
13.444 throw e;
13.445 }
13.446 }
13.447
13.448 // this call is BLOCKING
13.449 public Pair<DockerContainer, ActionStreamResult> run(String name, JSONObject configuration) throws DockerException {
13.450 - Socket s = null;
13.451 + Endpoint s = null;
13.452 try {
13.453 - URL url = createURL(instance.getUrl(), null);
13.454 - s = createSocket(url);
13.455 + s = createEndpoint();
13.456
13.457 byte[] data = configuration.toJSONString().getBytes("UTF-8");
13.458 Map<String, String> defaultHeaders = DockerConfig.getDefault().getHttpHeaders();
13.459 @@ -914,12 +928,13 @@
13.460 error != null ? error : response.getMessage());
13.461 }
13.462
13.463 - is = HttpUtils.getResponseStream(is, response);
13.464 + // we send a second request to the stream later
13.465 + InputStream nis = HttpUtils.getResponseStream(is, response, false);
13.466
13.467 JSONObject value;
13.468 try {
13.469 JSONParser parser = new JSONParser();
13.470 - value = (JSONObject) parser.parse(HttpUtils.readContent(is, response));
13.471 + value = (JSONObject) parser.parse(HttpUtils.readContent(nis, response));
13.472 } catch (ParseException ex) {
13.473 throw new DockerException(ex);
13.474 }
13.475 @@ -947,29 +962,33 @@
13.476
13.477 return Pair.of(container, r);
13.478 } catch (MalformedURLException e) {
13.479 - closeSocket(s);
13.480 + closeEndpoint(s);
13.481 throw new DockerException(e);
13.482 } catch (IOException e) {
13.483 - closeSocket(s);
13.484 + closeEndpoint(s);
13.485 throw new DockerException(e);
13.486 } catch (DockerException e) {
13.487 - closeSocket(s);
13.488 + closeEndpoint(s);
13.489 throw e;
13.490 }
13.491 }
13.492
13.493 - boolean ping() {
13.494 + public boolean ping() {
13.495 assert !SwingUtilities.isEventDispatchThread() : "Remote access invoked from EDT";
13.496 try {
13.497 - URL httpUrl = createURL(instance.getUrl(), "/_ping");
13.498 - HttpURLConnection conn = createConnection(httpUrl);
13.499 + Endpoint s = createEndpoint();
13.500 try {
13.501 - conn.setRequestMethod("GET");
13.502 - return conn.getResponseCode() == HttpURLConnection.HTTP_OK;
13.503 + OutputStream os = s.getOutputStream();
13.504 + // FIXME should we use default headers ?
13.505 + os.write(("GET /_ping HTTP/1.1\r\n\r\n").getBytes("ISO-8859-1"));
13.506 + os.flush();
13.507 +
13.508 + InputStream is = s.getInputStream();
13.509 + HttpUtils.Response response = HttpUtils.readResponse(is);
13.510 + return response.getCode() == HttpURLConnection.HTTP_OK;
13.511 } finally {
13.512 - conn.disconnect();
13.513 + closeEndpoint(s);
13.514 }
13.515 -
13.516 } catch (MalformedURLException ex) {
13.517 LOGGER.log(Level.INFO, null, ex);
13.518 } catch (IOException ex) {
13.519 @@ -983,8 +1002,7 @@
13.520 assert !SwingUtilities.isEventDispatchThread() : "Remote access invoked from EDT";
13.521
13.522 try {
13.523 - URL url = createURL(instance.getUrl(), null);
13.524 - Socket s = createSocket(url);
13.525 + Endpoint s = createEndpoint();
13.526 try {
13.527 OutputStream os = s.getOutputStream();
13.528 os.write(("GET " + (since != null ? "/events?since=" + since : "/events") + " HTTP/1.1\r\n"
13.529 @@ -1001,7 +1019,7 @@
13.530 error != null ? error : response.getMessage());
13.531 }
13.532
13.533 - is = HttpUtils.getResponseStream(is, response);
13.534 + is = HttpUtils.getResponseStream(is, response, false);
13.535
13.536 if (connectionListener != null) {
13.537 connectionListener.onConnect(s);
13.538 @@ -1031,7 +1049,7 @@
13.539 }
13.540 }
13.541 } finally {
13.542 - closeSocket(s);
13.543 + closeEndpoint(s);
13.544 }
13.545 } catch (MalformedURLException e) {
13.546 throw new DockerException(e);
13.547 @@ -1040,33 +1058,40 @@
13.548 }
13.549 }
13.550
13.551 - private Object doGetRequest(@NonNull String url, @NonNull String action, Set<Integer> okCodes) throws DockerException {
13.552 + private Object doGetRequest(@NonNull String action, Set<Integer> okCodes) throws DockerException {
13.553 assert !SwingUtilities.isEventDispatchThread() : "Remote access invoked from EDT";
13.554
13.555 try {
13.556 - URL httpUrl = createURL(url, action);
13.557 - HttpURLConnection conn = createConnection(httpUrl);
13.558 + Endpoint s = createEndpoint();
13.559 try {
13.560 - conn.setRequestMethod("GET");
13.561 - HttpUtils.configureHeaders(conn, DockerConfig.getDefault().getHttpHeaders(), ACCEPT_JSON_HEADER);
13.562 + OutputStream os = s.getOutputStream();
13.563 + os.write(("GET " + action + " HTTP/1.1\r\n").getBytes("ISO-8859-1"));
13.564 + HttpUtils.configureHeaders(os, DockerConfig.getDefault().getHttpHeaders(), ACCEPT_JSON_HEADER);
13.565 + os.write(("\r\n").getBytes("ISO-8859-1"));
13.566 + os.flush();
13.567
13.568 - if (!okCodes.contains(conn.getResponseCode())) {
13.569 - String error = HttpUtils.readError(conn);
13.570 - throw codeToException(conn.getResponseCode(),
13.571 - error != null ? error : conn.getResponseMessage());
13.572 + InputStream is = s.getInputStream();
13.573 + HttpUtils.Response response = HttpUtils.readResponse(is);
13.574 + int responseCode = response.getCode();
13.575 +
13.576 + if (!okCodes.contains(responseCode)) {
13.577 + String error = HttpUtils.readContent(is, response);
13.578 + throw codeToException(responseCode,
13.579 + error != null ? error : response.getMessage());
13.580 }
13.581
13.582 + is = HttpUtils.getResponseStream(is, response, false);
13.583 +
13.584 try (BufferedReader br = new BufferedReader(new InputStreamReader(
13.585 - (conn.getInputStream())))) {
13.586 + is, HttpUtils.getCharset(response)))) {
13.587 JSONParser parser = new JSONParser();
13.588 return parser.parse(br);
13.589 } catch (ParseException ex) {
13.590 throw new DockerException(ex);
13.591 }
13.592 } finally {
13.593 - conn.disconnect();
13.594 + closeEndpoint(s);
13.595 }
13.596 -
13.597 } catch (MalformedURLException e) {
13.598 throw new DockerException(e);
13.599 } catch (IOException e) {
13.600 @@ -1074,34 +1099,33 @@
13.601 }
13.602 }
13.603
13.604 - private Object doPostRequest(@NonNull String url, @NonNull String action,
13.605 - @NullAllowed InputStream data, boolean output, Set<Integer> okCodes) throws DockerException {
13.606 + private Object doPostRequest(@NonNull String action, boolean output, Set<Integer> okCodes) throws DockerException {
13.607 assert !SwingUtilities.isEventDispatchThread() : "Remote access invoked from EDT";
13.608
13.609 try {
13.610 - URL httpUrl = createURL(url, action);
13.611 - HttpURLConnection conn = createConnection(httpUrl);
13.612 + Endpoint s = createEndpoint();
13.613 try {
13.614 - conn.setRequestMethod("POST");
13.615 - HttpUtils.configureHeaders(conn, DockerConfig.getDefault().getHttpHeaders(),
13.616 + OutputStream os = s.getOutputStream();
13.617 + os.write(("POST " + action + " HTTP/1.1\r\n").getBytes("ISO-8859-1"));
13.618 + HttpUtils.configureHeaders(os, DockerConfig.getDefault().getHttpHeaders(),
13.619 Pair.of("Content-Type", "application/json"));
13.620 + os.write(("\r\n").getBytes("ISO-8859-1"));
13.621 + os.flush();
13.622
13.623 - if (data != null) {
13.624 - conn.setDoOutput(true);
13.625 - try (OutputStream os = new BufferedOutputStream(conn.getOutputStream())) {
13.626 - FileUtil.copy(data, os);
13.627 - }
13.628 - }
13.629 + InputStream is = s.getInputStream();
13.630 + HttpUtils.Response response = HttpUtils.readResponse(is);
13.631 + int responseCode = response.getCode();
13.632
13.633 - if (!okCodes.contains(conn.getResponseCode())) {
13.634 - String error = HttpUtils.readError(conn);
13.635 - throw codeToException(conn.getResponseCode(),
13.636 - error != null ? error : conn.getResponseMessage());
13.637 + if (!okCodes.contains(responseCode)) {
13.638 + String error = HttpUtils.readContent(is, response);
13.639 + throw codeToException(responseCode,
13.640 + error != null ? error : response.getMessage());
13.641 }
13.642
13.643 if (output) {
13.644 + is = HttpUtils.getResponseStream(is, response, false);
13.645 try (BufferedReader br = new BufferedReader(new InputStreamReader(
13.646 - (conn.getInputStream())))) {
13.647 + is, HttpUtils.getCharset(response)))) {
13.648 JSONParser parser = new JSONParser();
13.649 return parser.parse(br);
13.650 } catch (ParseException ex) {
13.651 @@ -1111,9 +1135,8 @@
13.652 return null;
13.653 }
13.654 } finally {
13.655 - conn.disconnect();
13.656 + closeEndpoint(s);
13.657 }
13.658 -
13.659 } catch (MalformedURLException e) {
13.660 throw new DockerException(e);
13.661 } catch (IOException e) {
13.662 @@ -1121,25 +1144,32 @@
13.663 }
13.664 }
13.665
13.666 - private Object doDeleteRequest(@NonNull String url, @NonNull String action, boolean output, Set<Integer> okCodes) throws DockerException {
13.667 + private Object doDeleteRequest(@NonNull String action, boolean output, Set<Integer> okCodes) throws DockerException {
13.668 assert !SwingUtilities.isEventDispatchThread() : "Remote access invoked from EDT";
13.669
13.670 try {
13.671 - URL httpUrl = createURL(url, action);
13.672 - HttpURLConnection conn = createConnection(httpUrl);
13.673 + Endpoint s = createEndpoint();
13.674 try {
13.675 - conn.setRequestMethod("DELETE");
13.676 - HttpUtils.configureHeaders(conn, DockerConfig.getDefault().getHttpHeaders(), ACCEPT_JSON_HEADER);
13.677 + OutputStream os = s.getOutputStream();
13.678 + os.write(("DELETE " + action + " HTTP/1.1\r\n").getBytes("ISO-8859-1"));
13.679 + HttpUtils.configureHeaders(os, DockerConfig.getDefault().getHttpHeaders(), ACCEPT_JSON_HEADER);
13.680 + os.write(("\r\n").getBytes("ISO-8859-1"));
13.681 + os.flush();
13.682
13.683 - if (!okCodes.contains(conn.getResponseCode())) {
13.684 - String error = HttpUtils.readError(conn);
13.685 - throw codeToException(conn.getResponseCode(),
13.686 - error != null ? error : conn.getResponseMessage());
13.687 + InputStream is = s.getInputStream();
13.688 + HttpUtils.Response response = HttpUtils.readResponse(is);
13.689 + int responseCode = response.getCode();
13.690 +
13.691 + if (!okCodes.contains(responseCode)) {
13.692 + String error = HttpUtils.readContent(is, response);
13.693 + throw codeToException(responseCode,
13.694 + error != null ? error : response.getMessage());
13.695 }
13.696
13.697 if (output) {
13.698 + is = HttpUtils.getResponseStream(is, response, false);
13.699 try (BufferedReader br = new BufferedReader(new InputStreamReader(
13.700 - (conn.getInputStream())))) {
13.701 + is, HttpUtils.getCharset(response)))) {
13.702 JSONParser parser = new JSONParser();
13.703 return parser.parse(br);
13.704 } catch (ParseException ex) {
13.705 @@ -1149,9 +1179,8 @@
13.706 return null;
13.707 }
13.708 } finally {
13.709 - conn.disconnect();
13.710 + closeEndpoint(s);
13.711 }
13.712 -
13.713 } catch (MalformedURLException e) {
13.714 throw new DockerException(e);
13.715 } catch (IOException e) {
13.716 @@ -1183,57 +1212,37 @@
13.717 return new StatusEvent(instance, id, status, progress, error, detail);
13.718 }
13.719
13.720 - private Socket createSocket(URL url) throws IOException {
13.721 - assert "http".equals(url.getProtocol()) || "https".equals(url.getProtocol()); // NOI18N
13.722 + private Endpoint createEndpoint() throws IOException {
13.723 + String url = instance.getUrl();
13.724 + if (url.startsWith("tcp://")) { // NOI18N
13.725 + url = "http://" + url.substring(6); // NOI18N
13.726 + } else if (url.startsWith("unix://")) { // NOI18N
13.727 + url = "file://" + url.substring(7); // NOI18N
13.728 + }
13.729 + URL realUrl = new URL(url);
13.730 try {
13.731 - if ("https".equals(url.getProtocol())) { // NOI18N
13.732 + if ("https".equals(realUrl.getProtocol())) { // NOI18N
13.733 SSLContext context = ContextProvider.getInstance().getSSLContext(instance);
13.734 - return context.getSocketFactory().createSocket(url.getHost(), url.getPort());
13.735 + return Endpoint.forSocket(context.getSocketFactory().createSocket(realUrl.getHost(), realUrl.getPort()));
13.736 + } else if ("http".equals(realUrl.getProtocol())) { // NOI18N
13.737 + Socket s = new Socket(ProxySelector.getDefault().select(realUrl.toURI()).get(0));
13.738 + int port = realUrl.getPort();
13.739 + if (port < 0) {
13.740 + port = realUrl.getDefaultPort();
13.741 + }
13.742 + s.connect(new InetSocketAddress(realUrl.getHost(), port));
13.743 + return Endpoint.forSocket(s);
13.744 } else {
13.745 - Socket s = new Socket(ProxySelector.getDefault().select(url.toURI()).get(0));
13.746 - int port = url.getPort();
13.747 - if (port < 0) {
13.748 - port = url.getDefaultPort();
13.749 - }
13.750 - s.connect(new InetSocketAddress(url.getHost(), port));
13.751 - return s;
13.752 + UnixDomainSocketClient s = new UnixDomainSocketClient(
13.753 + new File(realUrl.toURI()).getAbsolutePath(), JUDS.SOCK_STREAM);
13.754 + s.setTimeout(0);
13.755 + return Endpoint.forDomainSocket(s);
13.756 }
13.757 } catch (URISyntaxException ex) {
13.758 throw new IOException(ex);
13.759 }
13.760 }
13.761
13.762 - private HttpURLConnection createConnection(URL url) throws IOException {
13.763 - assert "http".equals(url.getProtocol()) || "https".equals(url.getProtocol()); // NOI18N
13.764 - try {
13.765 - HttpURLConnection ret = (HttpURLConnection) url.openConnection(ProxySelector.getDefault().select(url.toURI()).get(0));
13.766 - if (ret instanceof HttpsURLConnection) {
13.767 - ((HttpsURLConnection) ret).setSSLSocketFactory(ContextProvider.getInstance().getSSLContext(instance).getSocketFactory());
13.768 - }
13.769 - return ret;
13.770 - } catch (URISyntaxException ex) {
13.771 - throw new IOException(ex);
13.772 - }
13.773 - }
13.774 -
13.775 - private static URL createURL(@NonNull String url, @NullAllowed String action) throws MalformedURLException, UnsupportedEncodingException {
13.776 - // FIXME optimize
13.777 - String realUrl;
13.778 - if (url.startsWith("tcp://")) {
13.779 - realUrl = "http://" + url.substring(6);
13.780 - } else {
13.781 - realUrl = url;
13.782 - }
13.783 - if (realUrl.endsWith("/")) {
13.784 - realUrl = realUrl.substring(0, realUrl.length() - 1);
13.785 - }
13.786 - if (action != null) {
13.787 - realUrl += action;
13.788 - }
13.789 -
13.790 - return new URL(realUrl);
13.791 - }
13.792 -
13.793 private static JSONObject createAuthObject(Credentials credentials) {
13.794 JSONObject value = new JSONObject();
13.795 if (credentials == null) {
13.796 @@ -1298,7 +1307,7 @@
13.797 return null;
13.798 }
13.799
13.800 - private static void closeSocket(Socket s) {
13.801 + private static void closeEndpoint(Endpoint s) {
13.802 if (s != null) {
13.803 try {
13.804 s.close();
13.805 @@ -1395,18 +1404,18 @@
13.806
13.807 private static class CancelHandler {
13.808
13.809 - private Socket socket;
13.810 + private Endpoint endpoint;
13.811
13.812 private boolean cancelled;
13.813
13.814 - public synchronized void setSocket(Socket socket) {
13.815 - this.socket = socket;
13.816 + public synchronized void setEndpoint(Endpoint endpoint) {
13.817 + this.endpoint = endpoint;
13.818 }
13.819
13.820 public synchronized void cancel() {
13.821 - if (socket != null) {
13.822 - closeSocket(socket);
13.823 - socket = null;
13.824 + if (endpoint != null) {
13.825 + closeEndpoint(endpoint);
13.826 + endpoint = null;
13.827 cancelled = true;
13.828 }
13.829 }
14.1 --- a/docker.api/src/org/netbeans/modules/docker/api/DockerInstance.java Wed Mar 23 21:02:01 2016 +0000
14.2 +++ b/docker.api/src/org/netbeans/modules/docker/api/DockerInstance.java Thu Mar 24 15:34:03 2016 +0100
14.3 @@ -53,7 +53,6 @@
14.4 import java.util.prefs.PreferenceChangeEvent;
14.5 import java.util.prefs.PreferenceChangeListener;
14.6 import java.util.prefs.Preferences;
14.7 -import javax.swing.SwingUtilities;
14.8 import javax.swing.event.ChangeListener;
14.9 import org.netbeans.api.annotations.common.NonNull;
14.10 import org.netbeans.api.annotations.common.NullAllowed;
14.11 @@ -88,116 +87,63 @@
14.12
14.13 private final String url;
14.14
14.15 - private final Preferences prefs;
14.16 + // GuardedBy("this")
14.17 + private String displayName;
14.18 +
14.19 + // GuardedBy("this")
14.20 + private File caCertificate;
14.21 +
14.22 + // GuardedBy("this")
14.23 + private File certificate;
14.24 +
14.25 + // GuardedBy("this")
14.26 + private File key;
14.27 +
14.28 + // GuardedBy("this")
14.29 + private Preferences prefs;
14.30
14.31 private final DockerEventBus eventBus = new DockerEventBus(this);
14.32
14.33 - private DockerInstance(String url, Preferences prefs) {
14.34 + private DockerInstance(String url, String displayName, File caCertificate, File certificate, File key) {
14.35 this.url = url;
14.36 - this.prefs = prefs;
14.37 + this.displayName = displayName;
14.38 + this.caCertificate = caCertificate;
14.39 + this.certificate = certificate;
14.40 + this.key = key;
14.41 }
14.42
14.43 @NonNull
14.44 - static DockerInstance create(@NonNull String displayName, @NonNull String url,
14.45 + public static DockerInstance getInstance(@NonNull String url, @NullAllowed String displayName,
14.46 @NullAllowed File caCertificate, @NullAllowed File certificate, @NullAllowed File key) {
14.47 - Preferences global = NbPreferences.forModule(DockerInstance.class).node(INSTANCES_KEY);
14.48
14.49 - // XXX synchronization ?
14.50 - Preferences prefs = null;
14.51 - int suffix = 0;
14.52 - do {
14.53 - prefs = global.node(escapeUrl(url) + suffix);
14.54 - suffix++;
14.55 - } while (prefs.get(URL_KEY, null) != null && suffix < Integer.MAX_VALUE);
14.56 -
14.57 - prefs.put(DISPLAY_NAME_KEY, displayName);
14.58 - prefs.put(URL_KEY, url);
14.59 - if (caCertificate != null) {
14.60 - prefs.put(CA_CERTIFICATE_PATH_KEY, FileUtil.normalizeFile(caCertificate).getAbsolutePath());
14.61 - }
14.62 - if (certificate != null) {
14.63 - prefs.put(CERTIFICATE_PATH_KEY, FileUtil.normalizeFile(certificate).getAbsolutePath());
14.64 - }
14.65 - if (key != null) {
14.66 - prefs.put(KEY_PATH_KEY, FileUtil.normalizeFile(key).getAbsolutePath());
14.67 - }
14.68 - try {
14.69 - prefs.flush();
14.70 - } catch (BackingStoreException ex) {
14.71 - // XXX better solution?
14.72 - throw new IllegalStateException(ex);
14.73 - }
14.74 - DockerInstance instance = new DockerInstance(url, prefs);
14.75 - instance.init();
14.76 - return instance;
14.77 + return new DockerInstance(url, displayName, caCertificate, certificate, key);
14.78 }
14.79
14.80 - static Collection<? extends DockerInstance> findAll() {
14.81 - Preferences global = NbPreferences.forModule(DockerInstance.class).node(INSTANCES_KEY);
14.82 - assert global != null;
14.83 -
14.84 - List<DockerInstance> instances = new ArrayList<>();
14.85 - try {
14.86 - String[] names = global.childrenNames();
14.87 - if (names.length == 0) {
14.88 - LOGGER.log(Level.INFO, "No preferences nodes");
14.89 - }
14.90 - for (String name : names) {
14.91 - Preferences p = global.node(name);
14.92 - String displayName = p.get(DISPLAY_NAME_KEY, null);
14.93 - String url = p.get(URL_KEY, null);
14.94 - if (displayName != null && url != null) {
14.95 - DockerInstance instance = new DockerInstance(url, p);
14.96 - instance.init();
14.97 - instances.add(instance);
14.98 - } else {
14.99 - LOGGER.log(Level.INFO, "Invalid Docker instance {0}", name);
14.100 - }
14.101 - }
14.102 - LOGGER.log(Level.FINE, "Loaded {0} Docker instances", instances.size());
14.103 - } catch (BackingStoreException ex) {
14.104 - LOGGER.log(Level.WARNING, null, ex);
14.105 - }
14.106 - return instances;
14.107 + public String getUrl() {
14.108 + return url;
14.109 }
14.110
14.111 public String getDisplayName() {
14.112 - return prefs.get(DISPLAY_NAME_KEY, null);
14.113 - }
14.114 -
14.115 - public String getUrl() {
14.116 - return prefs.get(URL_KEY, null);
14.117 + synchronized (this) {
14.118 + return displayName;
14.119 + }
14.120 }
14.121
14.122 public File getCaCertificateFile() {
14.123 - String path = prefs.get(CA_CERTIFICATE_PATH_KEY, null);
14.124 - return path == null ? null : new File(path);
14.125 + synchronized (this) {
14.126 + return caCertificate;
14.127 + }
14.128 }
14.129
14.130 public File getCertificateFile() {
14.131 - String path = prefs.get(CERTIFICATE_PATH_KEY, null);
14.132 - return path == null ? null : new File(path);
14.133 + synchronized (this) {
14.134 + return certificate;
14.135 + }
14.136 }
14.137
14.138 public File getKeyFile() {
14.139 - String path = prefs.get(KEY_PATH_KEY, null);
14.140 - return path == null ? null : new File(path);
14.141 - }
14.142 -
14.143 - public boolean isAvailable() {
14.144 - if (SwingUtilities.isEventDispatchThread()) {
14.145 - throw new IllegalStateException("Method isConnected might block the EDT");
14.146 - }
14.147 - return new DockerAction(this).ping();
14.148 - }
14.149 -
14.150 - public void remove() {
14.151 - eventBus.close();
14.152 - try {
14.153 - prefs.removePreferenceChangeListener(listener);
14.154 - prefs.removeNode();
14.155 - } catch (BackingStoreException ex) {
14.156 - LOGGER.log(Level.WARNING, null, ex);
14.157 + synchronized (this) {
14.158 + return key;
14.159 }
14.160 }
14.161
14.162 @@ -263,12 +209,118 @@
14.163 return "DockerInstance{" + "url=" + url + '}';
14.164 }
14.165
14.166 - DockerEventBus getEventBus() {
14.167 - return eventBus;
14.168 + static Collection<? extends DockerInstance> loadAll() {
14.169 + Preferences global = NbPreferences.forModule(DockerInstance.class).node(INSTANCES_KEY);
14.170 + assert global != null;
14.171 +
14.172 + List<DockerInstance> instances = new ArrayList<>();
14.173 + try {
14.174 + String[] names = global.childrenNames();
14.175 + if (names.length == 0) {
14.176 + LOGGER.log(Level.INFO, "No preferences nodes");
14.177 + }
14.178 + for (String name : names) {
14.179 + Preferences p = global.node(name);
14.180 + String displayName = p.get(DISPLAY_NAME_KEY, null);
14.181 + String url = p.get(URL_KEY, null);
14.182 + if (displayName != null && url != null
14.183 + && (!url.startsWith("file:") || DockerSupport.getDefault().isSocketSupported())) { // NOI18N
14.184 + DockerInstance instance = new DockerInstance(url, null, null, null, null);
14.185 + instance.load(p);
14.186 +
14.187 + instances.add(instance);
14.188 + } else {
14.189 + LOGGER.log(Level.INFO, "Invalid Docker instance {0}", name);
14.190 + }
14.191 + }
14.192 + LOGGER.log(Level.FINE, "Loaded {0} Docker instances", instances.size());
14.193 + } catch (BackingStoreException ex) {
14.194 + LOGGER.log(Level.WARNING, null, ex);
14.195 + }
14.196 + return instances;
14.197 }
14.198
14.199 - private void init() {
14.200 - prefs.addPreferenceChangeListener(listener);
14.201 + final void save() {
14.202 + synchronized (this) {
14.203 + if (prefs != null) {
14.204 + throw new IllegalStateException();
14.205 + }
14.206 +
14.207 + Preferences global = NbPreferences.forModule(DockerInstance.class).node(INSTANCES_KEY);
14.208 +
14.209 + Preferences p = null;
14.210 + int suffix = 0;
14.211 + do {
14.212 + p = global.node(escapeUrl(url) + suffix);
14.213 + suffix++;
14.214 + } while (p.get(URL_KEY, null) != null && suffix < Integer.MAX_VALUE);
14.215 +
14.216 + p.put(DISPLAY_NAME_KEY, displayName);
14.217 + p.put(URL_KEY, url);
14.218 + if (caCertificate != null) {
14.219 + p.put(CA_CERTIFICATE_PATH_KEY, FileUtil.normalizeFile(caCertificate).getAbsolutePath());
14.220 + }
14.221 + if (certificate != null) {
14.222 + p.put(CERTIFICATE_PATH_KEY, FileUtil.normalizeFile(certificate).getAbsolutePath());
14.223 + }
14.224 + if (key != null) {
14.225 + p.put(KEY_PATH_KEY, FileUtil.normalizeFile(key).getAbsolutePath());
14.226 + }
14.227 + try {
14.228 + p.flush();
14.229 + } catch (BackingStoreException ex) {
14.230 + // XXX better solution?
14.231 + throw new IllegalStateException(ex);
14.232 + }
14.233 + this.prefs = p;
14.234 + this.prefs.addPreferenceChangeListener(listener);
14.235 + }
14.236 + }
14.237 +
14.238 + final void delete() {
14.239 + synchronized (this) {
14.240 + if (prefs == null) {
14.241 + throw new IllegalStateException();
14.242 + }
14.243 + try {
14.244 + prefs.removePreferenceChangeListener(listener);
14.245 + prefs.removeNode();
14.246 + } catch (BackingStoreException ex) {
14.247 + LOGGER.log(Level.WARNING, null, ex);
14.248 + }
14.249 + prefs = null;
14.250 + }
14.251 + }
14.252 +
14.253 + private final void load(Preferences p) {
14.254 + synchronized (this) {
14.255 + if (prefs != null) {
14.256 + throw new IllegalStateException();
14.257 + }
14.258 + prefs = p;
14.259 + prefs.addPreferenceChangeListener(listener);
14.260 + refresh();
14.261 + }
14.262 + }
14.263 +
14.264 + private void refresh() {
14.265 + synchronized (this) {
14.266 + if (prefs == null) {
14.267 + return;
14.268 + }
14.269 +
14.270 + displayName = prefs.get(DISPLAY_NAME_KEY, null);
14.271 + String caCertPath = prefs.get(CA_CERTIFICATE_PATH_KEY, null);
14.272 + caCertificate = caCertPath == null ? null : new File(caCertPath);
14.273 + String certPath = prefs.get(CERTIFICATE_PATH_KEY, null);
14.274 + certificate = certPath == null ? null : new File(certPath);
14.275 + String keyPath = prefs.get(KEY_PATH_KEY, null);
14.276 + key = keyPath == null ? null : new File(keyPath);
14.277 + }
14.278 + }
14.279 +
14.280 + final DockerEventBus getEventBus() {
14.281 + return eventBus;
14.282 }
14.283
14.284 private static String escapeUrl(String url) {
14.285 @@ -286,6 +338,7 @@
14.286
14.287 @Override
14.288 public void preferenceChange(PreferenceChangeEvent evt) {
14.289 + refresh();
14.290 changeSupport.fireChange();
14.291 }
14.292 }
15.1 --- a/docker.api/src/org/netbeans/modules/docker/api/DockerIntegration.java Wed Mar 23 21:02:01 2016 +0000
15.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
15.3 @@ -1,163 +0,0 @@
15.4 -/*
15.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
15.6 - *
15.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
15.8 - *
15.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
15.10 - * Other names may be trademarks of their respective owners.
15.11 - *
15.12 - * The contents of this file are subject to the terms of either the GNU
15.13 - * General Public License Version 2 only ("GPL") or the Common
15.14 - * Development and Distribution License("CDDL") (collectively, the
15.15 - * "License"). You may not use this file except in compliance with the
15.16 - * License. You can obtain a copy of the License at
15.17 - * http://www.netbeans.org/cddl-gplv2.html
15.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
15.19 - * specific language governing permissions and limitations under the
15.20 - * License. When distributing the software, include this License Header
15.21 - * Notice in each file and include the License file at
15.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
15.23 - * particular file as subject to the "Classpath" exception as provided
15.24 - * by Oracle in the GPL Version 2 section of the License file that
15.25 - * accompanied this code. If applicable, add the following below the
15.26 - * License Header, with the fields enclosed by brackets [] replaced by
15.27 - * your own identifying information:
15.28 - * "Portions Copyrighted [year] [name of copyright owner]"
15.29 - *
15.30 - * If you wish your version of this file to be governed by only the CDDL
15.31 - * or only the GPL Version 2, indicate your decision by adding
15.32 - * "[Contributor] elects to include this software in this distribution
15.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
15.34 - * single choice of license, a recipient has the option to distribute
15.35 - * your version of this file under either the CDDL, the GPL Version 2 or
15.36 - * to extend the choice of license to its licensees as provided above.
15.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
15.38 - * Version 2 license, then the option applies only if the new code is
15.39 - * made subject to such option by the copyright holder.
15.40 - *
15.41 - * Contributor(s):
15.42 - *
15.43 - * Portions Copyrighted 2007 Sun Microsystems, Inc.
15.44 - */
15.45 -
15.46 -package org.netbeans.modules.docker.api;
15.47 -
15.48 -import java.io.File;
15.49 -import java.util.Collection;
15.50 -import java.util.HashMap;
15.51 -import java.util.HashSet;
15.52 -import java.util.Map;
15.53 -import java.util.Set;
15.54 -import java.util.logging.Logger;
15.55 -import java.util.prefs.NodeChangeEvent;
15.56 -import java.util.prefs.NodeChangeListener;
15.57 -import java.util.prefs.Preferences;
15.58 -import javax.swing.event.ChangeListener;
15.59 -import org.netbeans.api.annotations.common.NonNull;
15.60 -import org.netbeans.api.annotations.common.NullAllowed;
15.61 -import org.openide.util.ChangeSupport;
15.62 -import org.openide.util.NbPreferences;
15.63 -import org.openide.util.Parameters;
15.64 -
15.65 -/**
15.66 - *
15.67 - * @author Petr Hejl
15.68 - */
15.69 -public final class DockerIntegration {
15.70 -
15.71 - private static final Logger LOGGER = Logger.getLogger(DockerIntegration.class.getName());
15.72 -
15.73 - private static DockerIntegration registry;
15.74 -
15.75 - private final ChangeSupport changeSupport = new ChangeSupport(this);
15.76 -
15.77 - // GuardedBy("this")
15.78 - private final Map<String, DockerInstance> instances = new HashMap<>();
15.79 -
15.80 - // GuardedBy("this")
15.81 - private boolean initialized;
15.82 -
15.83 - private DockerIntegration() {
15.84 - super();
15.85 - }
15.86 -
15.87 - public static DockerIntegration getDefault() {
15.88 - DockerIntegration ret;
15.89 - synchronized (DockerIntegration.class) {
15.90 - if (registry == null) {
15.91 - registry = new DockerIntegration();
15.92 - Preferences p = NbPreferences.forModule(DockerInstance.class).node(DockerInstance.INSTANCES_KEY);
15.93 - p.addNodeChangeListener(new NodeChangeListener() {
15.94 - @Override
15.95 - public void childAdded(NodeChangeEvent evt) {
15.96 - registry.refresh();
15.97 - }
15.98 -
15.99 - @Override
15.100 - public void childRemoved(NodeChangeEvent evt) {
15.101 - registry.refresh();
15.102 - }
15.103 - });
15.104 - }
15.105 - ret = registry;
15.106 - }
15.107 - synchronized (ret) {
15.108 - if (!ret.initialized) {
15.109 - ret.refresh();
15.110 - }
15.111 - }
15.112 - return ret;
15.113 - }
15.114 -
15.115 - public DockerInstance createInstance(@NonNull String displayName, @NonNull String url,
15.116 - @NullAllowed File caCertificate, @NullAllowed File certificate, @NullAllowed File key) {
15.117 - Parameters.notNull("displayName", displayName);
15.118 - Parameters.notNull("url", url);
15.119 -
15.120 - DockerInstance instance;
15.121 - synchronized (this) {
15.122 - if (instances.containsKey(url)) {
15.123 - throw new IllegalStateException("Docker instance already exist: " + url);
15.124 - }
15.125 - instance = DockerInstance.create(displayName, url, caCertificate, certificate, key);
15.126 - instances.put(url, instance);
15.127 - }
15.128 - changeSupport.fireChange();
15.129 - return instance;
15.130 - }
15.131 -
15.132 - public Collection<? extends DockerInstance> getInstances() {
15.133 - synchronized (this) {
15.134 - return new HashSet<>(instances.values());
15.135 - }
15.136 - }
15.137 -
15.138 - public void addChangeListener(ChangeListener listener) {
15.139 - changeSupport.addChangeListener(listener);
15.140 - }
15.141 -
15.142 - public void removeChangeListener(ChangeListener listener) {
15.143 - changeSupport.removeChangeListener(listener);
15.144 - }
15.145 -
15.146 - private void refresh() {
15.147 - boolean fire = false;
15.148 - synchronized (this) {
15.149 - initialized = true;
15.150 - Set<String> toRemove = new HashSet<>(instances.keySet());
15.151 - for (DockerInstance i : DockerInstance.findAll()) {
15.152 - if (instances.get(i.getUrl()) == null) {
15.153 - fire = true;
15.154 - instances.put(i.getUrl(), i);
15.155 - }
15.156 - toRemove.remove(i.getUrl());
15.157 - }
15.158 - if (instances.keySet().removeAll(toRemove)) {
15.159 - fire = true;
15.160 - }
15.161 - }
15.162 - if (fire) {
15.163 - changeSupport.fireChange();
15.164 - }
15.165 - }
15.166 -}
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
16.2 +++ b/docker.api/src/org/netbeans/modules/docker/api/DockerSupport.java Thu Mar 24 15:34:03 2016 +0100
16.3 @@ -0,0 +1,188 @@
16.4 +/*
16.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
16.6 + *
16.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
16.8 + *
16.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
16.10 + * Other names may be trademarks of their respective owners.
16.11 + *
16.12 + * The contents of this file are subject to the terms of either the GNU
16.13 + * General Public License Version 2 only ("GPL") or the Common
16.14 + * Development and Distribution License("CDDL") (collectively, the
16.15 + * "License"). You may not use this file except in compliance with the
16.16 + * License. You can obtain a copy of the License at
16.17 + * http://www.netbeans.org/cddl-gplv2.html
16.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16.19 + * specific language governing permissions and limitations under the
16.20 + * License. When distributing the software, include this License Header
16.21 + * Notice in each file and include the License file at
16.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
16.23 + * particular file as subject to the "Classpath" exception as provided
16.24 + * by Oracle in the GPL Version 2 section of the License file that
16.25 + * accompanied this code. If applicable, add the following below the
16.26 + * License Header, with the fields enclosed by brackets [] replaced by
16.27 + * your own identifying information:
16.28 + * "Portions Copyrighted [year] [name of copyright owner]"
16.29 + *
16.30 + * If you wish your version of this file to be governed by only the CDDL
16.31 + * or only the GPL Version 2, indicate your decision by adding
16.32 + * "[Contributor] elects to include this software in this distribution
16.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
16.34 + * single choice of license, a recipient has the option to distribute
16.35 + * your version of this file under either the CDDL, the GPL Version 2 or
16.36 + * to extend the choice of license to its licensees as provided above.
16.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
16.38 + * Version 2 license, then the option applies only if the new code is
16.39 + * made subject to such option by the copyright holder.
16.40 + *
16.41 + * Contributor(s):
16.42 + *
16.43 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
16.44 + */
16.45 +
16.46 +package org.netbeans.modules.docker.api;
16.47 +
16.48 +import java.util.Collection;
16.49 +import java.util.HashMap;
16.50 +import java.util.HashSet;
16.51 +import java.util.Map;
16.52 +import java.util.Set;
16.53 +import java.util.logging.Level;
16.54 +import java.util.logging.Logger;
16.55 +import java.util.prefs.NodeChangeEvent;
16.56 +import java.util.prefs.NodeChangeListener;
16.57 +import java.util.prefs.Preferences;
16.58 +import javax.swing.event.ChangeListener;
16.59 +import org.netbeans.api.annotations.common.NonNull;
16.60 +import org.openide.util.BaseUtilities;
16.61 +import org.openide.util.ChangeSupport;
16.62 +import org.openide.util.NbPreferences;
16.63 +import org.openide.util.Parameters;
16.64 +
16.65 +/**
16.66 + *
16.67 + * @author Petr Hejl
16.68 + */
16.69 +public final class DockerSupport {
16.70 +
16.71 + private static final Logger LOGGER = Logger.getLogger(DockerSupport.class.getName());
16.72 +
16.73 + private static DockerSupport support;
16.74 +
16.75 + private final ChangeSupport changeSupport = new ChangeSupport(this);
16.76 +
16.77 + // GuardedBy("this")
16.78 + private final Map<String, DockerInstance> instances = new HashMap<>();
16.79 +
16.80 + // GuardedBy("this")
16.81 + private boolean initialized;
16.82 +
16.83 + private DockerSupport() {
16.84 + super();
16.85 + }
16.86 +
16.87 + public static DockerSupport getDefault() {
16.88 + DockerSupport ret;
16.89 + synchronized (DockerSupport.class) {
16.90 + if (support == null) {
16.91 + support = new DockerSupport();
16.92 + Preferences p = NbPreferences.forModule(DockerInstance.class).node(DockerInstance.INSTANCES_KEY);
16.93 + p.addNodeChangeListener(new NodeChangeListener() {
16.94 + @Override
16.95 + public void childAdded(NodeChangeEvent evt) {
16.96 + support.refresh();
16.97 + }
16.98 +
16.99 + @Override
16.100 + public void childRemoved(NodeChangeEvent evt) {
16.101 + support.refresh();
16.102 + }
16.103 + });
16.104 + }
16.105 + ret = support;
16.106 + }
16.107 + synchronized (ret) {
16.108 + if (!ret.isInitialized()) {
16.109 + ret.refresh();
16.110 + }
16.111 + }
16.112 + return ret;
16.113 + }
16.114 +
16.115 + public DockerInstance addInstance(@NonNull DockerInstance instance) {
16.116 + Parameters.notNull("instance", instance);
16.117 +
16.118 + String url = instance.getUrl();
16.119 + synchronized (this) {
16.120 + if (instances.containsKey(url)) {
16.121 + throw new IllegalStateException("Docker instance already exist: " + url);
16.122 + }
16.123 + instance.save();
16.124 + instances.put(url, instance);
16.125 + }
16.126 + changeSupport.fireChange();
16.127 + return instance;
16.128 + }
16.129 +
16.130 + public void removeInstance(@NonNull DockerInstance instance) {
16.131 + Parameters.notNull("instance", instance);
16.132 +
16.133 + synchronized (this) {
16.134 + instances.remove(instance.getUrl());
16.135 + instance.delete();
16.136 +
16.137 + // we shouldn't need it and use it
16.138 + //instance.getEventBus().close();
16.139 + }
16.140 + changeSupport.fireChange();
16.141 + }
16.142 +
16.143 + public Collection<? extends DockerInstance> getInstances() {
16.144 + synchronized (this) {
16.145 + return new HashSet<>(instances.values());
16.146 + }
16.147 + }
16.148 +
16.149 + public void addChangeListener(ChangeListener listener) {
16.150 + changeSupport.addChangeListener(listener);
16.151 + }
16.152 +
16.153 + public void removeChangeListener(ChangeListener listener) {
16.154 + changeSupport.removeChangeListener(listener);
16.155 + }
16.156 +
16.157 + public boolean isSocketSupported() {
16.158 + if (BaseUtilities.getOperatingSystem() != BaseUtilities.OS_LINUX) {
16.159 + return false;
16.160 + }
16.161 + String arch = System.getProperty("os.arch"); // NOI18N
16.162 + return arch != null && (arch.contains("x86") || arch.contains("amd64")); // NOI18N
16.163 + }
16.164 +
16.165 + private boolean isInitialized() {
16.166 + synchronized (this) {
16.167 + return initialized;
16.168 + }
16.169 + }
16.170 +
16.171 + private void refresh() {
16.172 + boolean fire = false;
16.173 + synchronized (this) {
16.174 + initialized = true;
16.175 + Set<String> toRemove = new HashSet<>(instances.keySet());
16.176 + for (DockerInstance i : DockerInstance.loadAll()) {
16.177 + if (instances.get(i.getUrl()) == null) {
16.178 + fire = true;
16.179 + instances.put(i.getUrl(), i);
16.180 + }
16.181 + toRemove.remove(i.getUrl());
16.182 + }
16.183 + if (instances.keySet().removeAll(toRemove)) {
16.184 + fire = true;
16.185 + }
16.186 + }
16.187 + if (fire) {
16.188 + changeSupport.fireChange();
16.189 + }
16.190 + }
16.191 +}
17.1 --- a/docker.ui/nbproject/project.xml Wed Mar 23 21:02:01 2016 +0000
17.2 +++ b/docker.ui/nbproject/project.xml Thu Mar 24 15:34:03 2016 +0100
17.3 @@ -115,7 +115,7 @@
17.4 <compile-dependency/>
17.5 <run-dependency>
17.6 <release-version>0-1</release-version>
17.7 - <specification-version>1.15</specification-version>
17.8 + <specification-version>1.19</specification-version>
17.9 </run-dependency>
17.10 </dependency>
17.11 <dependency>
17.12 @@ -180,7 +180,7 @@
17.13 <build-prerequisite/>
17.14 <compile-dependency/>
17.15 <run-dependency>
17.16 - <specification-version>7.9</specification-version>
17.17 + <specification-version>7.45</specification-version>
17.18 </run-dependency>
17.19 </dependency>
17.20 <dependency>
18.1 --- a/docker.ui/src/org/netbeans/modules/docker/ui/build2/BuildImageAction.java Wed Mar 23 21:02:01 2016 +0000
18.2 +++ b/docker.ui/src/org/netbeans/modules/docker/ui/build2/BuildImageAction.java Thu Mar 24 15:34:03 2016 +0100
18.3 @@ -42,7 +42,7 @@
18.4 package org.netbeans.modules.docker.ui.build2;
18.5
18.6 import org.netbeans.modules.docker.api.DockerInstance;
18.7 -import org.netbeans.modules.docker.ui.node.EnhancedDockerInstance;
18.8 +import org.netbeans.modules.docker.ui.node.StatefulDockerInstance;
18.9 import org.openide.nodes.Node;
18.10 import org.openide.util.HelpCtx;
18.11 import org.openide.util.NbBundle;
18.12 @@ -66,7 +66,7 @@
18.13 if (activatedNodes.length != 1) {
18.14 return false;
18.15 }
18.16 - EnhancedDockerInstance checked = activatedNodes[0].getLookup().lookup(EnhancedDockerInstance.class);
18.17 + StatefulDockerInstance checked = activatedNodes[0].getLookup().lookup(StatefulDockerInstance.class);
18.18 if (checked == null || !checked.isAvailable()) {
18.19 return false;
18.20 }
19.1 --- a/docker.ui/src/org/netbeans/modules/docker/ui/build2/BuildImageWizard.java Wed Mar 23 21:02:01 2016 +0000
19.2 +++ b/docker.ui/src/org/netbeans/modules/docker/ui/build2/BuildImageWizard.java Thu Mar 24 15:34:03 2016 +0100
19.3 @@ -58,7 +58,7 @@
19.4 import org.netbeans.modules.docker.api.DockerInstance;
19.5 import org.netbeans.modules.docker.api.DockerAction;
19.6 import org.netbeans.modules.docker.api.DockerImage;
19.7 -import org.netbeans.modules.docker.api.DockerIntegration;
19.8 +import org.netbeans.modules.docker.api.DockerSupport;
19.9 import org.netbeans.modules.docker.ui.build2.InputOutputCache.CachedInputOutput;
19.10 import org.openide.DialogDisplayer;
19.11 import org.openide.WizardDescriptor;
19.12 @@ -312,7 +312,7 @@
19.13 this.listener = new ActionStateListener(this, buildTask.getInstance(), fo);
19.14
19.15 fo.addFileChangeListener(listener);
19.16 - DockerIntegration.getDefault().addChangeListener(listener);
19.17 + DockerSupport.getDefault().addChangeListener(listener);
19.18
19.19 listener.refresh();
19.20 }
19.21 @@ -325,7 +325,7 @@
19.22 FileObject fo = listener.getFileObject();
19.23
19.24 fo.removeFileChangeListener(listener);
19.25 - DockerIntegration.getDefault().removeChangeListener(listener);
19.26 + DockerSupport.getDefault().removeChangeListener(listener);
19.27
19.28 buildTask = null;
19.29 listener = null;
19.30 @@ -428,7 +428,7 @@
19.31 action.detach();
19.32 }
19.33 DockerInstance inst = this.instance.get();
19.34 - DockerIntegration integration = DockerIntegration.getDefault();
19.35 + DockerSupport integration = DockerSupport.getDefault();
19.36 if (inst == null || !integration.getInstances().contains(inst)) {
19.37 action.detach();
19.38 }
20.1 --- a/docker.ui/src/org/netbeans/modules/docker/ui/build2/BuildInstanceVisual.java Wed Mar 23 21:02:01 2016 +0000
20.2 +++ b/docker.ui/src/org/netbeans/modules/docker/ui/build2/BuildInstanceVisual.java Thu Mar 24 15:34:03 2016 +0100
20.3 @@ -52,7 +52,7 @@
20.4 import javax.swing.event.ChangeEvent;
20.5 import javax.swing.event.ChangeListener;
20.6 import org.netbeans.modules.docker.api.DockerInstance;
20.7 -import org.netbeans.modules.docker.api.DockerIntegration;
20.8 +import org.netbeans.modules.docker.api.DockerSupport;
20.9 import org.netbeans.modules.docker.ui.UiUtils;
20.10 import org.netbeans.modules.docker.ui.wizard.AddDockerInstanceWizard;
20.11 import org.openide.util.ChangeSupport;
20.12 @@ -91,7 +91,7 @@
20.13 public BuildInstanceVisual() {
20.14 initComponents();
20.15
20.16 - DockerIntegration integration = DockerIntegration.getDefault();
20.17 + DockerSupport integration = DockerSupport.getDefault();
20.18 integration.addChangeListener(WeakListeners.change(instancesListener, integration));
20.19
20.20 instanceComboBox.setModel(model);
20.21 @@ -144,7 +144,7 @@
20.22 assert SwingUtilities.isEventDispatchThread();
20.23 DockerInstanceWrapper wrapper = (DockerInstanceWrapper) model.getSelectedItem();
20.24 model.removeAllElements();
20.25 - List<DockerInstance> instances = new ArrayList<>(DockerIntegration.getDefault().getInstances());
20.26 + List<DockerInstance> instances = new ArrayList<>(DockerSupport.getDefault().getInstances());
20.27 Collections.sort(instances, UiUtils.getInstanceComparator());
20.28 for (DockerInstance i : instances) {
20.29 model.addElement(new DockerInstanceWrapper(i));
21.1 --- a/docker.ui/src/org/netbeans/modules/docker/ui/node/AbstractContainerAction.java Wed Mar 23 21:02:01 2016 +0000
21.2 +++ b/docker.ui/src/org/netbeans/modules/docker/ui/node/AbstractContainerAction.java Thu Mar 24 15:34:03 2016 +0100
21.3 @@ -82,7 +82,7 @@
21.4 @Override
21.5 protected final void performAction(Node[] activatedNodes) {
21.6 for (final Node node : activatedNodes) {
21.7 - final EnhancedDockerContainer container = node.getLookup().lookup(EnhancedDockerContainer.class);
21.8 + final StatefulDockerContainer container = node.getLookup().lookup(StatefulDockerContainer.class);
21.9 if (container != null) {
21.10 final ProgressHandle handle = ProgressHandle.createHandle(getProgressMessage(container.getContainer()));
21.11 handle.start();
21.12 @@ -106,7 +106,7 @@
21.13 @Override
21.14 protected final boolean enable(Node[] activatedNodes) {
21.15 for (Node node : activatedNodes) {
21.16 - EnhancedDockerContainer container = node.getLookup().lookup(EnhancedDockerContainer.class);
21.17 + StatefulDockerContainer container = node.getLookup().lookup(StatefulDockerContainer.class);
21.18 if (container == null || !isEnabled(container.getDetail())) {
21.19 return false;
21.20 }
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
22.2 +++ b/docker.ui/src/org/netbeans/modules/docker/ui/node/DockerChildFactory.java Thu Mar 24 15:34:03 2016 +0100
22.3 @@ -0,0 +1,116 @@
22.4 +/*
22.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
22.6 + *
22.7 + * Copyright 2016 Oracle and/or its affiliates. All rights reserved.
22.8 + *
22.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
22.10 + * Other names may be trademarks of their respective owners.
22.11 + *
22.12 + * The contents of this file are subject to the terms of either the GNU
22.13 + * General Public License Version 2 only ("GPL") or the Common
22.14 + * Development and Distribution License("CDDL") (collectively, the
22.15 + * "License"). You may not use this file except in compliance with the
22.16 + * License. You can obtain a copy of the License at
22.17 + * http://www.netbeans.org/cddl-gplv2.html
22.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
22.19 + * specific language governing permissions and limitations under the
22.20 + * License. When distributing the software, include this License Header
22.21 + * Notice in each file and include the License file at
22.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
22.23 + * particular file as subject to the "Classpath" exception as provided
22.24 + * by Oracle in the GPL Version 2 section of the License file that
22.25 + * accompanied this code. If applicable, add the following below the
22.26 + * License Header, with the fields enclosed by brackets [] replaced by
22.27 + * your own identifying information:
22.28 + * "Portions Copyrighted [year] [name of copyright owner]"
22.29 + *
22.30 + * If you wish your version of this file to be governed by only the CDDL
22.31 + * or only the GPL Version 2, indicate your decision by adding
22.32 + * "[Contributor] elects to include this software in this distribution
22.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
22.34 + * single choice of license, a recipient has the option to distribute
22.35 + * your version of this file under either the CDDL, the GPL Version 2 or
22.36 + * to extend the choice of license to its licensees as provided above.
22.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
22.38 + * Version 2 license, then the option applies only if the new code is
22.39 + * made subject to such option by the copyright holder.
22.40 + *
22.41 + * Contributor(s):
22.42 + *
22.43 + * Portions Copyrighted 2016 Sun Microsystems, Inc.
22.44 + */
22.45 +package org.netbeans.modules.docker.ui.node;
22.46 +
22.47 +import java.util.ArrayList;
22.48 +import java.util.Collections;
22.49 +import java.util.List;
22.50 +import javax.swing.event.ChangeEvent;
22.51 +import javax.swing.event.ChangeListener;
22.52 +import org.netbeans.modules.docker.api.DockerInstance;
22.53 +import org.netbeans.modules.docker.api.DockerSupport;
22.54 +import org.netbeans.modules.docker.ui.UiUtils;
22.55 +import org.openide.nodes.Node;
22.56 +import org.openide.util.RequestProcessor;
22.57 +import org.openide.util.WeakListeners;
22.58 +
22.59 +/**
22.60 + *
22.61 + * @author Petr Hejl
22.62 + */
22.63 +public class DockerChildFactory extends NodeClosingFactory<StatefulDockerInstance> implements ChangeListener {
22.64 +
22.65 + private static final RequestProcessor REFRESH_PROCESSOR = new RequestProcessor("Docker node update/refresh", 5);
22.66 +
22.67 + private final DockerSupport registry;
22.68 +
22.69 + public DockerChildFactory(DockerSupport registry) {
22.70 + this.registry = registry;
22.71 + }
22.72 +
22.73 + public void init() {
22.74 + REFRESH_PROCESSOR.post(new Runnable() {
22.75 +
22.76 + @Override
22.77 + public void run() {
22.78 + synchronized (DockerChildFactory.this) {
22.79 + registry.addChangeListener(
22.80 + WeakListeners.create(ChangeListener.class, DockerChildFactory.this, registry));
22.81 + updateState(new ChangeEvent(registry));
22.82 + }
22.83 + }
22.84 + });
22.85 + }
22.86 +
22.87 + @Override
22.88 + public void stateChanged(final ChangeEvent e) {
22.89 + REFRESH_PROCESSOR.post(new Runnable() {
22.90 + public void run() {
22.91 + updateState(e);
22.92 + }
22.93 + });
22.94 + }
22.95 +
22.96 + private synchronized void updateState(final ChangeEvent e) {
22.97 + refresh();
22.98 + }
22.99 +
22.100 + protected final void refresh() {
22.101 + refresh(false);
22.102 + }
22.103 +
22.104 + @Override
22.105 + protected Node createNodeForKey(StatefulDockerInstance key) {
22.106 + return new DockerInstanceNode(key, new DockerInstanceChildFactory(key));
22.107 + }
22.108 +
22.109 + @Override
22.110 + protected boolean createKeys(List<StatefulDockerInstance> toPopulate) {
22.111 + List<DockerInstance> fresh = new ArrayList<>(registry.getInstances());
22.112 + Collections.sort(fresh, UiUtils.getInstanceComparator());
22.113 + for (DockerInstance i : fresh) {
22.114 + toPopulate.add(new StatefulDockerInstance(i));
22.115 + }
22.116 + return true;
22.117 + }
22.118 +
22.119 +}
23.1 --- a/docker.ui/src/org/netbeans/modules/docker/ui/node/DockerContainerNode.java Wed Mar 23 21:02:01 2016 +0000
23.2 +++ b/docker.ui/src/org/netbeans/modules/docker/ui/node/DockerContainerNode.java Thu Mar 24 15:34:03 2016 +0100
23.3 @@ -71,7 +71,7 @@
23.4 private static final String RUNNING_ICON
23.5 = "org/netbeans/modules/docker/ui/resources/badge_running.png"; // NOI18N
23.6
23.7 - private final EnhancedDockerContainer container;
23.8 + private final StatefulDockerContainer container;
23.9
23.10 private final ChangeListener listener = new ChangeListener() {
23.11 @Override
23.12 @@ -81,7 +81,7 @@
23.13 }
23.14 };
23.15
23.16 - public DockerContainerNode(EnhancedDockerContainer container) {
23.17 + public DockerContainerNode(StatefulDockerContainer container) {
23.18 super(Children.LEAF, Lookups.fixed(container.getContainer(), container));
23.19 this.container = container;
23.20 DockerContainer dockerContainer = container.getContainer();
24.1 --- a/docker.ui/src/org/netbeans/modules/docker/ui/node/DockerContainersChildFactory.java Wed Mar 23 21:02:01 2016 +0000
24.2 +++ b/docker.ui/src/org/netbeans/modules/docker/ui/node/DockerContainersChildFactory.java Thu Mar 24 15:34:03 2016 +0100
24.3 @@ -41,6 +41,7 @@
24.4 */
24.5 package org.netbeans.modules.docker.ui.node;
24.6
24.7 +import java.io.Closeable;
24.8 import java.lang.ref.WeakReference;
24.9 import java.util.ArrayList;
24.10 import java.util.Collections;
24.11 @@ -64,7 +65,7 @@
24.12 *
24.13 * @author Petr Hejl
24.14 */
24.15 -public class DockerContainersChildFactory extends ChildFactory<EnhancedDockerContainer> implements Refreshable {
24.16 +public class DockerContainersChildFactory extends NodeClosingFactory<StatefulDockerContainer> implements Refreshable, Closeable {
24.17
24.18 private static final Logger LOGGER = Logger.getLogger(DockerContainersChildFactory.class.getName());
24.19
24.20 @@ -72,17 +73,19 @@
24.21
24.22 @Override
24.23 public int compare(DockerContainer o1, DockerContainer o2) {
24.24 - return o1.getId().compareTo(o2.getId());
24.25 + return o1.getImage().compareTo(o2.getImage());
24.26 }
24.27 };
24.28
24.29 private static final Set<DockerEvent.Status> CHANGE_EVENTS = new HashSet<>();
24.30
24.31 static {
24.32 - Collections.addAll(CHANGE_EVENTS, DockerEvent.Status.COPY, DockerEvent.Status.CREATE, DockerEvent.Status.DESTROY);
24.33 + // rename is here because it may reorder nodes
24.34 + Collections.addAll(CHANGE_EVENTS, DockerEvent.Status.COPY, DockerEvent.Status.CREATE,
24.35 + DockerEvent.Status.DESTROY, DockerEvent.Status.RENAME);
24.36 }
24.37
24.38 - private final Map<DockerContainer, WeakReference<EnhancedDockerContainer>> cache = new WeakHashMap<>();
24.39 + private final Map<DockerContainer, WeakReference<StatefulDockerContainer>> cache = new WeakHashMap<>();
24.40
24.41 private final RequestProcessor requestProcessor = new RequestProcessor(DockerContainersChildFactory.class);
24.42
24.43 @@ -90,6 +93,8 @@
24.44
24.45 private final RequestProcessor.Task refreshTask;
24.46
24.47 + private final DockerEvent.Listener listener;
24.48 +
24.49 public DockerContainersChildFactory(DockerInstance instance) {
24.50 this.instance = instance;
24.51 this.refreshTask = requestProcessor.create(new Runnable() {
24.52 @@ -99,35 +104,36 @@
24.53 refresh();
24.54 }
24.55 });
24.56 - instance.addContainerListener(new DockerEvent.Listener() {
24.57 + this.listener = new DockerEvent.Listener() {
24.58 @Override
24.59 public void onEvent(DockerEvent event) {
24.60 if (CHANGE_EVENTS.contains(event.getStatus())) {
24.61 refreshTask.schedule(200);
24.62 }
24.63 }
24.64 - });
24.65 + };
24.66 + instance.addContainerListener(listener);
24.67 }
24.68
24.69 @Override
24.70 - protected Node createNodeForKey(EnhancedDockerContainer key) {
24.71 + protected Node createNodeForKey(StatefulDockerContainer key) {
24.72 return new DockerContainerNode(key);
24.73 }
24.74
24.75 @Override
24.76 - protected boolean createKeys(List<EnhancedDockerContainer> toPopulate) {
24.77 + protected boolean createKeys(List<StatefulDockerContainer> toPopulate) {
24.78 DockerAction facade = new DockerAction(instance);
24.79 List<DockerContainer> containers = new ArrayList<>(facade.getContainers());
24.80 Collections.sort(containers, COMPARATOR);
24.81 synchronized (cache) {
24.82 for (DockerContainer c : containers) {
24.83 - EnhancedDockerContainer cached = null;
24.84 - WeakReference<EnhancedDockerContainer> ref = cache.get(c);
24.85 + StatefulDockerContainer cached = null;
24.86 + WeakReference<StatefulDockerContainer> ref = cache.get(c);
24.87 if (ref != null) {
24.88 cached = ref.get();
24.89 }
24.90 if (cached == null) {
24.91 - cached = new EnhancedDockerContainer(c);
24.92 + cached = new StatefulDockerContainer(c);
24.93 cache.put(c, new WeakReference<>(cached));
24.94 } else {
24.95 cached.refresh();
24.96 @@ -143,4 +149,17 @@
24.97 refresh(false);
24.98 }
24.99
24.100 + @Override
24.101 + public void close() {
24.102 + instance.removeContainerListener(listener);
24.103 + synchronized (cache) {
24.104 + for (WeakReference<StatefulDockerContainer> r : cache.values()) {
24.105 + StatefulDockerContainer c = r.get();
24.106 + if (c != null) {
24.107 + c.close();
24.108 + }
24.109 + }
24.110 + }
24.111 + }
24.112 +
24.113 }
25.1 --- a/docker.ui/src/org/netbeans/modules/docker/ui/node/DockerImagesChildFactory.java Wed Mar 23 21:02:01 2016 +0000
25.2 +++ b/docker.ui/src/org/netbeans/modules/docker/ui/node/DockerImagesChildFactory.java Thu Mar 24 15:34:03 2016 +0100
25.3 @@ -41,6 +41,7 @@
25.4 */
25.5 package org.netbeans.modules.docker.ui.node;
25.6
25.7 +import java.io.Closeable;
25.8 import java.util.ArrayList;
25.9 import java.util.Collections;
25.10 import java.util.Comparator;
25.11 @@ -52,7 +53,6 @@
25.12 import org.netbeans.modules.docker.api.DockerTag;
25.13 import org.netbeans.modules.docker.api.DockerEvent;
25.14 import org.netbeans.modules.docker.api.DockerAction;
25.15 -import org.openide.nodes.ChildFactory;
25.16 import org.openide.nodes.Node;
25.17 import org.openide.util.RequestProcessor;
25.18
25.19 @@ -60,7 +60,7 @@
25.20 *
25.21 * @author Petr Hejl
25.22 */
25.23 -public class DockerImagesChildFactory extends ChildFactory<DockerTag> implements Refreshable {
25.24 +public class DockerImagesChildFactory extends NodeClosingFactory<DockerTag> implements Refreshable, Closeable {
25.25
25.26 private static final Logger LOGGER = Logger.getLogger(DockerImagesChildFactory.class.getName());
25.27
25.28 @@ -78,7 +78,7 @@
25.29
25.30 private final RequestProcessor.Task refreshTask;
25.31
25.32 - private DockerEvent lastEvent;
25.33 + private final DockerEvent.Listener listener;
25.34
25.35 public DockerImagesChildFactory(DockerInstance instance) {
25.36 this.instance = instance;
25.37 @@ -89,14 +89,15 @@
25.38 refresh();
25.39 }
25.40 });
25.41 - instance.addImageListener(new DockerEvent.Listener() {
25.42 + this.listener = new DockerEvent.Listener() {
25.43 @Override
25.44 public void onEvent(DockerEvent event) {
25.45 if (DockerEvent.Status.PUSH != event.getStatus()) {
25.46 refreshTask.schedule(200);
25.47 }
25.48 }
25.49 - });
25.50 + };
25.51 + instance.addImageListener(listener);
25.52 }
25.53
25.54 @Override
25.55 @@ -116,8 +117,14 @@
25.56 return true;
25.57 }
25.58
25.59 + @Override
25.60 public final void refresh() {
25.61 refresh(false);
25.62 }
25.63
25.64 + @Override
25.65 + public void close() {
25.66 + instance.removeImageListener(listener);
25.67 + }
25.68 +
25.69 }
26.1 --- a/docker.ui/src/org/netbeans/modules/docker/ui/node/DockerInstanceChildFactory.java Wed Mar 23 21:02:01 2016 +0000
26.2 +++ b/docker.ui/src/org/netbeans/modules/docker/ui/node/DockerInstanceChildFactory.java Thu Mar 24 15:34:03 2016 +0100
26.3 @@ -41,22 +41,32 @@
26.4 */
26.5 package org.netbeans.modules.docker.ui.node;
26.6
26.7 +import java.io.Closeable;
26.8 +import java.io.IOException;
26.9 +import java.util.Collections;
26.10 +import java.util.HashSet;
26.11 import java.util.List;
26.12 +import java.util.Set;
26.13 +import java.util.logging.Level;
26.14 +import java.util.logging.Logger;
26.15 import javax.swing.event.ChangeEvent;
26.16 import javax.swing.event.ChangeListener;
26.17 import org.netbeans.modules.docker.api.DockerInstance;
26.18 -import org.openide.nodes.ChildFactory;
26.19 import org.openide.nodes.Node;
26.20
26.21 /**
26.22 *
26.23 * @author Petr Hejl
26.24 */
26.25 -public class DockerInstanceChildFactory extends ChildFactory<Boolean> {
26.26 +public class DockerInstanceChildFactory extends NodeClosingFactory<Boolean> implements Closeable {
26.27
26.28 - private final EnhancedDockerInstance instance;
26.29 + private static final Logger LOGGER = Logger.getLogger(DockerInstanceChildFactory.class.getName());
26.30
26.31 - public DockerInstanceChildFactory(EnhancedDockerInstance instance) {
26.32 + private final StatefulDockerInstance instance;
26.33 +
26.34 + private final Set<Node> current = new HashSet<>();
26.35 +
26.36 + public DockerInstanceChildFactory(StatefulDockerInstance instance) {
26.37 this.instance = instance;
26.38
26.39 instance.addChangeListener(new ChangeListener() {
26.40 @@ -70,15 +80,21 @@
26.41
26.42 @Override
26.43 protected Node[] createNodesForKey(Boolean key) {
26.44 + Node[] ret;
26.45 if (key) {
26.46 DockerInstance dockerInstance = instance.getInstance();
26.47 DockerImagesChildFactory factoryRepo = new DockerImagesChildFactory(dockerInstance);
26.48 DockerContainersChildFactory factoryCont = new DockerContainersChildFactory(dockerInstance);
26.49 - return new Node[]{new DockerImagesNode(dockerInstance, factoryRepo),
26.50 + ret = new Node[]{new DockerImagesNode(dockerInstance, factoryRepo),
26.51 new DockerContainersNode(dockerInstance, factoryCont)};
26.52 } else {
26.53 - return new Node[] {};
26.54 + ret = new Node[] {};
26.55 }
26.56 + synchronized (current) {
26.57 + current.clear();
26.58 + Collections.addAll(current, ret);
26.59 + }
26.60 + return ret;
26.61 }
26.62
26.63 @Override
26.64 @@ -86,4 +102,21 @@
26.65 toPopulate.add(instance.isAvailable());
26.66 return true;
26.67 }
26.68 +
26.69 + @Override
26.70 + public void close() {
26.71 + Set<Node> nodes;
26.72 + synchronized (current) {
26.73 + nodes = new HashSet<>(current);
26.74 + }
26.75 + for (Node n : nodes) {
26.76 + for (Closeable c : n.getLookup().lookupAll(Closeable.class)) {
26.77 + try {
26.78 + c.close();
26.79 + } catch (IOException ex) {
26.80 + LOGGER.log(Level.INFO, null, ex);
26.81 + }
26.82 + }
26.83 + }
26.84 + }
26.85 }
27.1 --- a/docker.ui/src/org/netbeans/modules/docker/ui/node/DockerInstanceNode.java Wed Mar 23 21:02:01 2016 +0000
27.2 +++ b/docker.ui/src/org/netbeans/modules/docker/ui/node/DockerInstanceNode.java Thu Mar 24 15:34:03 2016 +0100
27.3 @@ -61,7 +61,7 @@
27.4
27.5 private static final String DOCKER_INSTANCE_ICON = "org/netbeans/modules/docker/ui/resources/docker_instance.png"; // NOI18N
27.6
27.7 - private final EnhancedDockerInstance instance;
27.8 + private final StatefulDockerInstance instance;
27.9
27.10 private final ChangeListener listener = new ChangeListener() {
27.11 @Override
27.12 @@ -70,9 +70,9 @@
27.13 }
27.14 };
27.15
27.16 - public DockerInstanceNode(EnhancedDockerInstance instance) {
27.17 - super(Children.create(new DockerInstanceChildFactory(instance), true),
27.18 - Lookups.fixed(instance.getInstance(), instance));
27.19 + public DockerInstanceNode(StatefulDockerInstance instance, DockerInstanceChildFactory factory) {
27.20 + super(Children.create(factory, true),
27.21 + Lookups.fixed(instance.getInstance(), instance, factory));
27.22 this.instance = instance;
27.23 setIconBaseWithExtension(DOCKER_INSTANCE_ICON);
27.24 setShortDescription(instance.getInstance().getUrl());
28.1 --- a/docker.ui/src/org/netbeans/modules/docker/ui/node/DockerNode.java Wed Mar 23 21:02:01 2016 +0000
28.2 +++ b/docker.ui/src/org/netbeans/modules/docker/ui/node/DockerNode.java Thu Mar 24 15:34:03 2016 +0100
28.3 @@ -44,19 +44,16 @@
28.4
28.5 package org.netbeans.modules.docker.ui.node;
28.6
28.7 -import java.io.Serializable;
28.8 import java.util.ArrayList;
28.9 import java.util.Collections;
28.10 -import java.util.Comparator;
28.11 import java.util.List;
28.12 -import java.util.logging.Level;
28.13 import java.util.logging.Logger;
28.14 import javax.swing.Action;
28.15 import javax.swing.event.ChangeEvent;
28.16 import javax.swing.event.ChangeListener;
28.17 import org.netbeans.api.core.ide.ServicesTabNodeRegistration;
28.18 import org.netbeans.modules.docker.api.DockerInstance;
28.19 -import org.netbeans.modules.docker.api.DockerIntegration;
28.20 +import org.netbeans.modules.docker.api.DockerSupport;
28.21 import org.netbeans.modules.docker.ui.UiUtils;
28.22 import org.openide.nodes.AbstractNode;
28.23 import org.openide.nodes.Children;
28.24 @@ -68,14 +65,11 @@
28.25
28.26 public final class DockerNode extends AbstractNode {
28.27
28.28 - private static final RequestProcessor REFRESH_PROCESSOR =
28.29 - new RequestProcessor("Docker node update/refresh", 5);
28.30 -
28.31 private static final String DOCKER_ICON = "org/netbeans/modules/docker/ui/resources/docker_root.png"; // NOI18N
28.32
28.33 private static DockerNode node;
28.34
28.35 - private DockerNode(ChildFactory factory, String displayName, String shortDesc, String iconBase) {
28.36 + private DockerNode(DockerChildFactory factory, String displayName, String shortDesc, String iconBase) {
28.37 super(Children.create(factory, true));
28.38
28.39 setName(""); // NOI18N
28.40 @@ -93,7 +87,7 @@
28.41 )
28.42 public static synchronized DockerNode getInstance() {
28.43 if (node == null) {
28.44 - ChildFactory factory = new ChildFactory(DockerIntegration.getDefault());
28.45 + DockerChildFactory factory = new DockerChildFactory(DockerSupport.getDefault());
28.46 factory.init();
28.47
28.48 node = new DockerNode(factory,
28.49 @@ -113,60 +107,4 @@
28.50 return ret.toArray(new Action[ret.size()]);
28.51 }
28.52
28.53 - private static class ChildFactory extends org.openide.nodes.ChildFactory<EnhancedDockerInstance>
28.54 - implements ChangeListener {
28.55 -
28.56 - private final DockerIntegration registry;
28.57 -
28.58 - public ChildFactory(DockerIntegration registry) {
28.59 - super();
28.60 - this.registry = registry;
28.61 - }
28.62 -
28.63 - public void init() {
28.64 - REFRESH_PROCESSOR.post(new Runnable() {
28.65 -
28.66 - public void run() {
28.67 - synchronized (ChildFactory.this) {
28.68 - registry.addChangeListener(
28.69 - WeakListeners.create(ChangeListener.class, ChildFactory.this, registry));
28.70 - updateState(new ChangeEvent(registry));
28.71 - }
28.72 - }
28.73 - });
28.74 - }
28.75 -
28.76 - public void stateChanged(final ChangeEvent e) {
28.77 - REFRESH_PROCESSOR.post(new Runnable() {
28.78 -
28.79 - public void run() {
28.80 - updateState(e);
28.81 - }
28.82 - });
28.83 - }
28.84 -
28.85 - private synchronized void updateState(final ChangeEvent e) {
28.86 - refresh();
28.87 - }
28.88 -
28.89 - protected final void refresh() {
28.90 - refresh(false);
28.91 - }
28.92 -
28.93 - @Override
28.94 - protected Node createNodeForKey(EnhancedDockerInstance key) {
28.95 - return new DockerInstanceNode(key);
28.96 - }
28.97 -
28.98 - @Override
28.99 - protected boolean createKeys(List<EnhancedDockerInstance> toPopulate) {
28.100 - List<DockerInstance> fresh = new ArrayList<>(registry.getInstances());
28.101 - Collections.sort(fresh, UiUtils.getInstanceComparator());
28.102 - for (DockerInstance i : fresh) {
28.103 - toPopulate.add(new EnhancedDockerInstance(i));
28.104 - }
28.105 - return true;
28.106 - }
28.107 -
28.108 - } // end of ChildFactory
28.109 }
29.1 --- a/docker.ui/src/org/netbeans/modules/docker/ui/node/EnhancedDockerContainer.java Wed Mar 23 21:02:01 2016 +0000
29.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
29.3 @@ -1,182 +0,0 @@
29.4 -/*
29.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
29.6 - *
29.7 - * Copyright 2015 Oracle and/or its affiliates. All rights reserved.
29.8 - *
29.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
29.10 - * Other names may be trademarks of their respective owners.
29.11 - *
29.12 - * The contents of this file are subject to the terms of either the GNU
29.13 - * General Public License Version 2 only ("GPL") or the Common
29.14 - * Development and Distribution License("CDDL") (collectively, the
29.15 - * "License"). You may not use this file except in compliance with the
29.16 - * License. You can obtain a copy of the License at
29.17 - * http://www.netbeans.org/cddl-gplv2.html
29.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
29.19 - * specific language governing permissions and limitations under the
29.20 - * License. When distributing the software, include this License Header
29.21 - * Notice in each file and include the License file at
29.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
29.23 - * particular file as subject to the "Classpath" exception as provided
29.24 - * by Oracle in the GPL Version 2 section of the License file that
29.25 - * accompanied this code. If applicable, add the following below the
29.26 - * License Header, with the fields enclosed by brackets [] replaced by
29.27 - * your own identifying information:
29.28 - * "Portions Copyrighted [year] [name of copyright owner]"
29.29 - *
29.30 - * If you wish your version of this file to be governed by only the CDDL
29.31 - * or only the GPL Version 2, indicate your decision by adding
29.32 - * "[Contributor] elects to include this software in this distribution
29.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
29.34 - * single choice of license, a recipient has the option to distribute
29.35 - * your version of this file under either the CDDL, the GPL Version 2 or
29.36 - * to extend the choice of license to its licensees as provided above.
29.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
29.38 - * Version 2 license, then the option applies only if the new code is
29.39 - * made subject to such option by the copyright holder.
29.40 - *
29.41 - * Contributor(s):
29.42 - *
29.43 - * Portions Copyrighted 2015 Sun Microsystems, Inc.
29.44 - */
29.45 -package org.netbeans.modules.docker.ui.node;
29.46 -
29.47 -import java.util.Objects;
29.48 -import java.util.logging.Level;
29.49 -import java.util.logging.Logger;
29.50 -import javax.swing.event.ChangeListener;
29.51 -import org.netbeans.modules.docker.api.DockerAction;
29.52 -import org.netbeans.modules.docker.api.DockerContainer;
29.53 -import org.netbeans.modules.docker.api.DockerContainerDetail;
29.54 -import org.netbeans.modules.docker.api.DockerEvent;
29.55 -import org.netbeans.modules.docker.api.DockerException;
29.56 -import org.openide.util.ChangeSupport;
29.57 -import org.openide.util.RequestProcessor;
29.58 -import org.openide.util.WeakListeners;
29.59 -
29.60 -/**
29.61 - *
29.62 - * @author Petr Hejl
29.63 - */
29.64 -public class EnhancedDockerContainer implements Refreshable {
29.65 -
29.66 - private static final Logger LOGGER = Logger.getLogger(EnhancedDockerContainer.class.getName());
29.67 -
29.68 - private static final RequestProcessor RP = new RequestProcessor(EnhancedDockerContainer.class);
29.69 -
29.70 - private final ChangeSupport changeSupport = new ChangeSupport(this);
29.71 -
29.72 - private final DockerEvent.Listener listener = new DockerEvent.Listener() {
29.73 - @Override
29.74 - public void onEvent(DockerEvent event) {
29.75 - if (event.getId().equals(EnhancedDockerContainer.this.container.getId())
29.76 - && event.getStatus() != DockerEvent.Status.DESTROY && event.getStatus() != DockerEvent.Status.UNTAG) {
29.77 - DockerContainer.Status fresh = getStatus(event);
29.78 - if (fresh != null) {
29.79 - update(fresh);
29.80 - } else {
29.81 - refresh();
29.82 - }
29.83 - }
29.84 - }
29.85 - };
29.86 -
29.87 - private final DockerContainer container;
29.88 -
29.89 - private DockerContainerDetail detail;
29.90 -
29.91 - public EnhancedDockerContainer(DockerContainer container) {
29.92 - this.container = container;
29.93 - this.detail = new DockerContainerDetail(container.getName(), container.getStatus(), false, false);
29.94 - container.getInstance().addContainerListener(
29.95 - WeakListeners.create(DockerEvent.Listener.class, listener, container.getInstance()));
29.96 - }
29.97 -
29.98 - public void addChangeListener(ChangeListener listener) {
29.99 - changeSupport.addChangeListener(listener);
29.100 - }
29.101 -
29.102 - public void removeChangeListener(ChangeListener listener) {
29.103 - changeSupport.removeChangeListener(listener);
29.104 - }
29.105 -
29.106 - public DockerContainer getContainer() {
29.107 - return container;
29.108 - }
29.109 -
29.110 - public DockerContainerDetail getDetail() {
29.111 - synchronized (this) {
29.112 - return detail;
29.113 - }
29.114 - }
29.115 -
29.116 - @Override
29.117 - public void refresh() {
29.118 - RP.post(new Runnable() {
29.119 - @Override
29.120 - public void run() {
29.121 - DockerAction action = new DockerAction(container.getInstance());
29.122 - try {
29.123 - update(action.getDetail(container));
29.124 - } catch (DockerException ex) {
29.125 - LOGGER.log(Level.INFO, null, ex);
29.126 - }
29.127 - }
29.128 - });
29.129 - }
29.130 -
29.131 - @Override
29.132 - public int hashCode() {
29.133 - int hash = 3;
29.134 - hash = 71 * hash + Objects.hashCode(this.container);
29.135 - return hash;
29.136 - }
29.137 -
29.138 - @Override
29.139 - public boolean equals(Object obj) {
29.140 - if (this == obj) {
29.141 - return true;
29.142 - }
29.143 - if (obj == null) {
29.144 - return false;
29.145 - }
29.146 - if (getClass() != obj.getClass()) {
29.147 - return false;
29.148 - }
29.149 - final EnhancedDockerContainer other = (EnhancedDockerContainer) obj;
29.150 - if (!Objects.equals(this.container, other.container)) {
29.151 - return false;
29.152 - }
29.153 - return true;
29.154 - }
29.155 -
29.156 - private void update(DockerContainer.Status status) {
29.157 - synchronized (this) {
29.158 - detail = new DockerContainerDetail(detail.getName(), status, detail.isStdin(), detail.isTty());
29.159 - }
29.160 - changeSupport.fireChange();
29.161 - }
29.162 -
29.163 - private void update(DockerContainerDetail value) {
29.164 - synchronized (this) {
29.165 - detail = value;
29.166 - }
29.167 - changeSupport.fireChange();
29.168 - }
29.169 -
29.170 - private static DockerContainer.Status getStatus(DockerEvent event) {
29.171 - DockerEvent.Status status = event.getStatus();
29.172 - switch (status) {
29.173 - case DIE:
29.174 - return DockerContainer.Status.STOPPED;
29.175 - case START:
29.176 - return DockerContainer.Status.RUNNING;
29.177 - case PAUSE:
29.178 - return DockerContainer.Status.PAUSED;
29.179 - case UNPAUSE:
29.180 - return DockerContainer.Status.RUNNING;
29.181 - default:
29.182 - return null;
29.183 - }
29.184 - }
29.185 -}
30.1 --- a/docker.ui/src/org/netbeans/modules/docker/ui/node/EnhancedDockerInstance.java Wed Mar 23 21:02:01 2016 +0000
30.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
30.3 @@ -1,146 +0,0 @@
30.4 -/*
30.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
30.6 - *
30.7 - * Copyright 2015 Oracle and/or its affiliates. All rights reserved.
30.8 - *
30.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
30.10 - * Other names may be trademarks of their respective owners.
30.11 - *
30.12 - * The contents of this file are subject to the terms of either the GNU
30.13 - * General Public License Version 2 only ("GPL") or the Common
30.14 - * Development and Distribution License("CDDL") (collectively, the
30.15 - * "License"). You may not use this file except in compliance with the
30.16 - * License. You can obtain a copy of the License at
30.17 - * http://www.netbeans.org/cddl-gplv2.html
30.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
30.19 - * specific language governing permissions and limitations under the
30.20 - * License. When distributing the software, include this License Header
30.21 - * Notice in each file and include the License file at
30.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
30.23 - * particular file as subject to the "Classpath" exception as provided
30.24 - * by Oracle in the GPL Version 2 section of the License file that
30.25 - * accompanied this code. If applicable, add the following below the
30.26 - * License Header, with the fields enclosed by brackets [] replaced by
30.27 - * your own identifying information:
30.28 - * "Portions Copyrighted [year] [name of copyright owner]"
30.29 - *
30.30 - * If you wish your version of this file to be governed by only the CDDL
30.31 - * or only the GPL Version 2, indicate your decision by adding
30.32 - * "[Contributor] elects to include this software in this distribution
30.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
30.34 - * single choice of license, a recipient has the option to distribute
30.35 - * your version of this file under either the CDDL, the GPL Version 2 or
30.36 - * to extend the choice of license to its licensees as provided above.
30.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
30.38 - * Version 2 license, then the option applies only if the new code is
30.39 - * made subject to such option by the copyright holder.
30.40 - *
30.41 - * Contributor(s):
30.42 - *
30.43 - * Portions Copyrighted 2015 Sun Microsystems, Inc.
30.44 - */
30.45 -package org.netbeans.modules.docker.ui.node;
30.46 -
30.47 -import java.util.Objects;
30.48 -import java.util.concurrent.atomic.AtomicBoolean;
30.49 -import javax.swing.event.ChangeListener;
30.50 -import org.netbeans.modules.docker.api.DockerInstance;
30.51 -import org.openide.util.ChangeSupport;
30.52 -import org.openide.util.RequestProcessor;
30.53 -import org.openide.util.WeakListeners;
30.54 -
30.55 -/**
30.56 - *
30.57 - * @author Petr Hejl
30.58 - */
30.59 -public class EnhancedDockerInstance implements Refreshable {
30.60 -
30.61 - private static final RequestProcessor RP = new RequestProcessor(EnhancedDockerInstance.class);
30.62 -
30.63 - private final ChangeSupport changeSupport = new ChangeSupport(this);
30.64 -
30.65 - // FIXME default value
30.66 - private final AtomicBoolean available = new AtomicBoolean(true);
30.67 -
30.68 - private final DockerInstance.ConnectionListener listener = new DockerInstance.ConnectionListener() {
30.69 - @Override
30.70 - public void onConnect() {
30.71 - update(true);
30.72 - }
30.73 -
30.74 - @Override
30.75 - public void onDisconnect() {
30.76 - update(false);
30.77 - }
30.78 - };
30.79 -
30.80 - private final DockerInstance instance;
30.81 -
30.82 - public EnhancedDockerInstance(DockerInstance instance) {
30.83 - this.instance = instance;
30.84 - instance.addConnectionListener(listener);
30.85 - }
30.86 -
30.87 - public void addChangeListener(ChangeListener listener) {
30.88 - changeSupport.addChangeListener(listener);
30.89 - }
30.90 -
30.91 - public void removeChangeListener(ChangeListener listener) {
30.92 - changeSupport.removeChangeListener(listener);
30.93 - }
30.94 -
30.95 - public DockerInstance getInstance() {
30.96 - return instance;
30.97 - }
30.98 -
30.99 - public boolean isAvailable() {
30.100 - return available.get();
30.101 - }
30.102 -
30.103 - @Override
30.104 - public void refresh() {
30.105 - RP.post(new Runnable() {
30.106 - @Override
30.107 - public void run() {
30.108 - update(instance.isAvailable());
30.109 - }
30.110 - });
30.111 - }
30.112 -
30.113 - public void remove() {
30.114 - instance.removeConnectionListener(listener);
30.115 - instance.remove();
30.116 - }
30.117 -
30.118 - @Override
30.119 - public int hashCode() {
30.120 - int hash = 7;
30.121 - hash = 61 * hash + Objects.hashCode(this.instance);
30.122 - return hash;
30.123 - }
30.124 -
30.125 - @Override
30.126 - public boolean equals(Object obj) {
30.127 - if (this == obj) {
30.128 - return true;
30.129 - }
30.130 - if (obj == null) {
30.131 - return false;
30.132 - }
30.133 - if (getClass() != obj.getClass()) {
30.134 - return false;
30.135 - }
30.136 - final EnhancedDockerInstance other = (EnhancedDockerInstance) obj;
30.137 - if (!Objects.equals(this.instance, other.instance)) {
30.138 - return false;
30.139 - }
30.140 - return true;
30.141 - }
30.142 -
30.143 - private void update(boolean newValue) {
30.144 - boolean oldValue = available.getAndSet(newValue);
30.145 - if (oldValue != newValue) {
30.146 - changeSupport.fireChange();
30.147 - }
30.148 - }
30.149 -}
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
31.2 +++ b/docker.ui/src/org/netbeans/modules/docker/ui/node/NodeClosingFactory.java Thu Mar 24 15:34:03 2016 +0100
31.3 @@ -0,0 +1,72 @@
31.4 +/*
31.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
31.6 + *
31.7 + * Copyright 2016 Oracle and/or its affiliates. All rights reserved.
31.8 + *
31.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
31.10 + * Other names may be trademarks of their respective owners.
31.11 + *
31.12 + * The contents of this file are subject to the terms of either the GNU
31.13 + * General Public License Version 2 only ("GPL") or the Common
31.14 + * Development and Distribution License("CDDL") (collectively, the
31.15 + * "License"). You may not use this file except in compliance with the
31.16 + * License. You can obtain a copy of the License at
31.17 + * http://www.netbeans.org/cddl-gplv2.html
31.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
31.19 + * specific language governing permissions and limitations under the
31.20 + * License. When distributing the software, include this License Header
31.21 + * Notice in each file and include the License file at
31.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
31.23 + * particular file as subject to the "Classpath" exception as provided
31.24 + * by Oracle in the GPL Version 2 section of the License file that
31.25 + * accompanied this code. If applicable, add the following below the
31.26 + * License Header, with the fields enclosed by brackets [] replaced by
31.27 + * your own identifying information:
31.28 + * "Portions Copyrighted [year] [name of copyright owner]"
31.29 + *
31.30 + * If you wish your version of this file to be governed by only the CDDL
31.31 + * or only the GPL Version 2, indicate your decision by adding
31.32 + * "[Contributor] elects to include this software in this distribution
31.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
31.34 + * single choice of license, a recipient has the option to distribute
31.35 + * your version of this file under either the CDDL, the GPL Version 2 or
31.36 + * to extend the choice of license to its licensees as provided above.
31.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
31.38 + * Version 2 license, then the option applies only if the new code is
31.39 + * made subject to such option by the copyright holder.
31.40 + *
31.41 + * Contributor(s):
31.42 + *
31.43 + * Portions Copyrighted 2016 Sun Microsystems, Inc.
31.44 + */
31.45 +package org.netbeans.modules.docker.ui.node;
31.46 +
31.47 +import java.io.Closeable;
31.48 +import java.io.IOException;
31.49 +import java.util.logging.Level;
31.50 +import java.util.logging.Logger;
31.51 +import org.openide.nodes.DestroyableNodesFactory;
31.52 +import org.openide.nodes.Node;
31.53 +
31.54 +/**
31.55 + *
31.56 + * @author Petr Hejl
31.57 + */
31.58 +public abstract class NodeClosingFactory<T> extends DestroyableNodesFactory<T> {
31.59 +
31.60 + private static final Logger LOGGER = Logger.getLogger(NodeClosingFactory.class.getName());
31.61 +
31.62 + @Override
31.63 + protected void destroyNodes(Node[] arr) {
31.64 + for (Node n : arr) {
31.65 + for (Closeable c : n.getLookup().lookupAll(Closeable.class)) {
31.66 + try {
31.67 + LOGGER.log(Level.FINE, "Closing {0}", c.getClass().getName());
31.68 + c.close();
31.69 + } catch (IOException ex) {
31.70 + LOGGER.log(Level.FINE, null, ex);
31.71 + }
31.72 + }
31.73 + }
31.74 + }
31.75 +}
32.1 --- a/docker.ui/src/org/netbeans/modules/docker/ui/node/RemoveInstanceAction.java Wed Mar 23 21:02:01 2016 +0000
32.2 +++ b/docker.ui/src/org/netbeans/modules/docker/ui/node/RemoveInstanceAction.java Thu Mar 24 15:34:03 2016 +0100
32.3 @@ -56,7 +56,7 @@
32.4 @Override
32.5 protected void performAction(Node[] activatedNodes) {
32.6 for (Node node : activatedNodes) {
32.7 - EnhancedDockerInstance instance = node.getLookup().lookup(EnhancedDockerInstance.class);
32.8 + StatefulDockerInstance instance = node.getLookup().lookup(StatefulDockerInstance.class);
32.9 if (instance != null) {
32.10 instance.remove();
32.11 }
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
33.2 +++ b/docker.ui/src/org/netbeans/modules/docker/ui/node/StatefulDockerContainer.java Thu Mar 24 15:34:03 2016 +0100
33.3 @@ -0,0 +1,190 @@
33.4 +/*
33.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
33.6 + *
33.7 + * Copyright 2015 Oracle and/or its affiliates. All rights reserved.
33.8 + *
33.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
33.10 + * Other names may be trademarks of their respective owners.
33.11 + *
33.12 + * The contents of this file are subject to the terms of either the GNU
33.13 + * General Public License Version 2 only ("GPL") or the Common
33.14 + * Development and Distribution License("CDDL") (collectively, the
33.15 + * "License"). You may not use this file except in compliance with the
33.16 + * License. You can obtain a copy of the License at
33.17 + * http://www.netbeans.org/cddl-gplv2.html
33.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
33.19 + * specific language governing permissions and limitations under the
33.20 + * License. When distributing the software, include this License Header
33.21 + * Notice in each file and include the License file at
33.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
33.23 + * particular file as subject to the "Classpath" exception as provided
33.24 + * by Oracle in the GPL Version 2 section of the License file that
33.25 + * accompanied this code. If applicable, add the following below the
33.26 + * License Header, with the fields enclosed by brackets [] replaced by
33.27 + * your own identifying information:
33.28 + * "Portions Copyrighted [year] [name of copyright owner]"
33.29 + *
33.30 + * If you wish your version of this file to be governed by only the CDDL
33.31 + * or only the GPL Version 2, indicate your decision by adding
33.32 + * "[Contributor] elects to include this software in this distribution
33.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
33.34 + * single choice of license, a recipient has the option to distribute
33.35 + * your version of this file under either the CDDL, the GPL Version 2 or
33.36 + * to extend the choice of license to its licensees as provided above.
33.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
33.38 + * Version 2 license, then the option applies only if the new code is
33.39 + * made subject to such option by the copyright holder.
33.40 + *
33.41 + * Contributor(s):
33.42 + *
33.43 + * Portions Copyrighted 2015 Sun Microsystems, Inc.
33.44 + */
33.45 +package org.netbeans.modules.docker.ui.node;
33.46 +
33.47 +import java.io.Closeable;
33.48 +import java.util.Objects;
33.49 +import java.util.logging.Level;
33.50 +import java.util.logging.Logger;
33.51 +import javax.swing.event.ChangeListener;
33.52 +import org.netbeans.modules.docker.api.DockerAction;
33.53 +import org.netbeans.modules.docker.api.DockerContainer;
33.54 +import org.netbeans.modules.docker.api.DockerContainerDetail;
33.55 +import org.netbeans.modules.docker.api.DockerEvent;
33.56 +import org.netbeans.modules.docker.api.DockerException;
33.57 +import org.openide.util.ChangeSupport;
33.58 +import org.openide.util.RequestProcessor;
33.59 +import org.openide.util.WeakListeners;
33.60 +
33.61 +/**
33.62 + *
33.63 + * @author Petr Hejl
33.64 + */
33.65 +public class StatefulDockerContainer implements Refreshable, Closeable {
33.66 +
33.67 + private static final Logger LOGGER = Logger.getLogger(StatefulDockerContainer.class.getName());
33.68 +
33.69 + private static final RequestProcessor RP = new RequestProcessor(StatefulDockerContainer.class);
33.70 +
33.71 + private final ChangeSupport changeSupport = new ChangeSupport(this);
33.72 +
33.73 + private final DockerEvent.Listener listener = new DockerEvent.Listener() {
33.74 + @Override
33.75 + public void onEvent(DockerEvent event) {
33.76 + if (event.getId().equals(StatefulDockerContainer.this.container.getId())
33.77 + && event.getStatus() != DockerEvent.Status.DESTROY && event.getStatus() != DockerEvent.Status.UNTAG) {
33.78 + DockerContainer.Status fresh = getStatus(event);
33.79 + if (fresh != null) {
33.80 + update(fresh);
33.81 + } else {
33.82 + refresh();
33.83 + }
33.84 + }
33.85 + }
33.86 + };
33.87 +
33.88 + private final DockerEvent.Listener weak;
33.89 +
33.90 + private final DockerContainer container;
33.91 +
33.92 + private DockerContainerDetail detail;
33.93 +
33.94 + public StatefulDockerContainer(DockerContainer container) {
33.95 + this.container = container;
33.96 + this.detail = new DockerContainerDetail(container.getName(), container.getStatus(), false, false);
33.97 + this.weak = WeakListeners.create(DockerEvent.Listener.class, listener, container.getInstance());
33.98 + container.getInstance().addContainerListener(weak);
33.99 + }
33.100 +
33.101 + public void addChangeListener(ChangeListener listener) {
33.102 + changeSupport.addChangeListener(listener);
33.103 + }
33.104 +
33.105 + public void removeChangeListener(ChangeListener listener) {
33.106 + changeSupport.removeChangeListener(listener);
33.107 + }
33.108 +
33.109 + public DockerContainer getContainer() {
33.110 + return container;
33.111 + }
33.112 +
33.113 + public DockerContainerDetail getDetail() {
33.114 + synchronized (this) {
33.115 + return detail;
33.116 + }
33.117 + }
33.118 +
33.119 + @Override
33.120 + public void refresh() {
33.121 + RP.post(new Runnable() {
33.122 + @Override
33.123 + public void run() {
33.124 + DockerAction action = new DockerAction(container.getInstance());
33.125 + try {
33.126 + update(action.getDetail(container));
33.127 + } catch (DockerException ex) {
33.128 + LOGGER.log(Level.INFO, null, ex);
33.129 + }
33.130 + }
33.131 + });
33.132 + }
33.133 +
33.134 + @Override
33.135 + public void close() {
33.136 + container.getInstance().removeContainerListener(weak);
33.137 + }
33.138 +
33.139 + @Override
33.140 + public int hashCode() {
33.141 + int hash = 3;
33.142 + hash = 71 * hash + Objects.hashCode(this.container);
33.143 + return hash;
33.144 + }
33.145 +
33.146 + @Override
33.147 + public boolean equals(Object obj) {
33.148 + if (this == obj) {
33.149 + return true;
33.150 + }
33.151 + if (obj == null) {
33.152 + return false;
33.153 + }
33.154 + if (getClass() != obj.getClass()) {
33.155 + return false;
33.156 + }
33.157 + final StatefulDockerContainer other = (StatefulDockerContainer) obj;
33.158 + if (!Objects.equals(this.container, other.container)) {
33.159 + return false;
33.160 + }
33.161 + return true;
33.162 + }
33.163 +
33.164 + private void update(DockerContainer.Status status) {
33.165 + synchronized (this) {
33.166 + detail = new DockerContainerDetail(detail.getName(), status, detail.isStdin(), detail.isTty());
33.167 + }
33.168 + changeSupport.fireChange();
33.169 + }
33.170 +
33.171 + private void update(DockerContainerDetail value) {
33.172 + synchronized (this) {
33.173 + detail = value;
33.174 + }
33.175 + changeSupport.fireChange();
33.176 + }
33.177 +
33.178 + private static DockerContainer.Status getStatus(DockerEvent event) {
33.179 + DockerEvent.Status status = event.getStatus();
33.180 + switch (status) {
33.181 + case DIE:
33.182 + return DockerContainer.Status.STOPPED;
33.183 + case START:
33.184 + return DockerContainer.Status.RUNNING;
33.185 + case PAUSE:
33.186 + return DockerContainer.Status.PAUSED;
33.187 + case UNPAUSE:
33.188 + return DockerContainer.Status.RUNNING;
33.189 + default:
33.190 + return null;
33.191 + }
33.192 + }
33.193 +}
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
34.2 +++ b/docker.ui/src/org/netbeans/modules/docker/ui/node/StatefulDockerInstance.java Thu Mar 24 15:34:03 2016 +0100
34.3 @@ -0,0 +1,147 @@
34.4 +/*
34.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
34.6 + *
34.7 + * Copyright 2015 Oracle and/or its affiliates. All rights reserved.
34.8 + *
34.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
34.10 + * Other names may be trademarks of their respective owners.
34.11 + *
34.12 + * The contents of this file are subject to the terms of either the GNU
34.13 + * General Public License Version 2 only ("GPL") or the Common
34.14 + * Development and Distribution License("CDDL") (collectively, the
34.15 + * "License"). You may not use this file except in compliance with the
34.16 + * License. You can obtain a copy of the License at
34.17 + * http://www.netbeans.org/cddl-gplv2.html
34.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
34.19 + * specific language governing permissions and limitations under the
34.20 + * License. When distributing the software, include this License Header
34.21 + * Notice in each file and include the License file at
34.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
34.23 + * particular file as subject to the "Classpath" exception as provided
34.24 + * by Oracle in the GPL Version 2 section of the License file that
34.25 + * accompanied this code. If applicable, add the following below the
34.26 + * License Header, with the fields enclosed by brackets [] replaced by
34.27 + * your own identifying information:
34.28 + * "Portions Copyrighted [year] [name of copyright owner]"
34.29 + *
34.30 + * If you wish your version of this file to be governed by only the CDDL
34.31 + * or only the GPL Version 2, indicate your decision by adding
34.32 + * "[Contributor] elects to include this software in this distribution
34.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
34.34 + * single choice of license, a recipient has the option to distribute
34.35 + * your version of this file under either the CDDL, the GPL Version 2 or
34.36 + * to extend the choice of license to its licensees as provided above.
34.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
34.38 + * Version 2 license, then the option applies only if the new code is
34.39 + * made subject to such option by the copyright holder.
34.40 + *
34.41 + * Contributor(s):
34.42 + *
34.43 + * Portions Copyrighted 2015 Sun Microsystems, Inc.
34.44 + */
34.45 +package org.netbeans.modules.docker.ui.node;
34.46 +
34.47 +import java.util.Objects;
34.48 +import java.util.concurrent.atomic.AtomicBoolean;
34.49 +import javax.swing.event.ChangeListener;
34.50 +import org.netbeans.modules.docker.api.DockerAction;
34.51 +import org.netbeans.modules.docker.api.DockerInstance;
34.52 +import org.netbeans.modules.docker.api.DockerSupport;
34.53 +import org.openide.util.ChangeSupport;
34.54 +import org.openide.util.RequestProcessor;
34.55 +
34.56 +/**
34.57 + *
34.58 + * @author Petr Hejl
34.59 + */
34.60 +public class StatefulDockerInstance implements Refreshable {
34.61 +
34.62 + private static final RequestProcessor RP = new RequestProcessor(StatefulDockerInstance.class);
34.63 +
34.64 + private final ChangeSupport changeSupport = new ChangeSupport(this);
34.65 +
34.66 + // FIXME default value
34.67 + private final AtomicBoolean available = new AtomicBoolean(true);
34.68 +
34.69 + private final DockerInstance.ConnectionListener listener = new DockerInstance.ConnectionListener() {
34.70 + @Override
34.71 + public void onConnect() {
34.72 + update(true);
34.73 + }
34.74 +
34.75 + @Override
34.76 + public void onDisconnect() {
34.77 + update(false);
34.78 + }
34.79 + };
34.80 +
34.81 + private final DockerInstance instance;
34.82 +
34.83 + public StatefulDockerInstance(DockerInstance instance) {
34.84 + this.instance = instance;
34.85 + instance.addConnectionListener(listener);
34.86 + }
34.87 +
34.88 + public void addChangeListener(ChangeListener listener) {
34.89 + changeSupport.addChangeListener(listener);
34.90 + }
34.91 +
34.92 + public void removeChangeListener(ChangeListener listener) {
34.93 + changeSupport.removeChangeListener(listener);
34.94 + }
34.95 +
34.96 + public DockerInstance getInstance() {
34.97 + return instance;
34.98 + }
34.99 +
34.100 + public boolean isAvailable() {
34.101 + return available.get();
34.102 + }
34.103 +
34.104 + @Override
34.105 + public void refresh() {
34.106 + RP.post(new Runnable() {
34.107 + @Override
34.108 + public void run() {
34.109 + update(new DockerAction(instance).ping());
34.110 + }
34.111 + });
34.112 + }
34.113 +
34.114 + public void remove() {
34.115 + instance.removeConnectionListener(listener);
34.116 + DockerSupport.getDefault().removeInstance(instance);
34.117 + }
34.118 +
34.119 + @Override
34.120 + public int hashCode() {
34.121 + int hash = 7;
34.122 + hash = 61 * hash + Objects.hashCode(this.instance);
34.123 + return hash;
34.124 + }
34.125 +
34.126 + @Override
34.127 + public boolean equals(Object obj) {
34.128 + if (this == obj) {
34.129 + return true;
34.130 + }
34.131 + if (obj == null) {
34.132 + return false;
34.133 + }
34.134 + if (getClass() != obj.getClass()) {
34.135 + return false;
34.136 + }
34.137 + final StatefulDockerInstance other = (StatefulDockerInstance) obj;
34.138 + if (!Objects.equals(this.instance, other.instance)) {
34.139 + return false;
34.140 + }
34.141 + return true;
34.142 + }
34.143 +
34.144 + private void update(boolean newValue) {
34.145 + boolean oldValue = available.getAndSet(newValue);
34.146 + if (oldValue != newValue) {
34.147 + changeSupport.fireChange();
34.148 + }
34.149 + }
34.150 +}
35.1 --- a/docker.ui/src/org/netbeans/modules/docker/ui/pull/PullImageAction.java Wed Mar 23 21:02:01 2016 +0000
35.2 +++ b/docker.ui/src/org/netbeans/modules/docker/ui/pull/PullImageAction.java Thu Mar 24 15:34:03 2016 +0100
35.3 @@ -59,7 +59,7 @@
35.4 import org.netbeans.modules.docker.api.DockerAuthenticationException;
35.5 import org.netbeans.modules.docker.api.DockerName;
35.6 import org.netbeans.modules.docker.ui.credentials.CredentialsUtils;
35.7 -import org.netbeans.modules.docker.ui.node.EnhancedDockerInstance;
35.8 +import org.netbeans.modules.docker.ui.node.StatefulDockerInstance;
35.9 import org.openide.DialogDescriptor;
35.10 import org.openide.DialogDisplayer;
35.11 import org.openide.NotifyDescriptor;
35.12 @@ -123,7 +123,7 @@
35.13 if (activatedNodes.length != 1) {
35.14 return false;
35.15 }
35.16 - EnhancedDockerInstance checked = activatedNodes[0].getLookup().lookup(EnhancedDockerInstance.class);
35.17 + StatefulDockerInstance checked = activatedNodes[0].getLookup().lookup(StatefulDockerInstance.class);
35.18 if (checked == null || !checked.isAvailable()) {
35.19 return false;
35.20 }
36.1 --- a/docker.ui/src/org/netbeans/modules/docker/ui/rename/RenameContainerAction.java Wed Mar 23 21:02:01 2016 +0000
36.2 +++ b/docker.ui/src/org/netbeans/modules/docker/ui/rename/RenameContainerAction.java Thu Mar 24 15:34:03 2016 +0100
36.3 @@ -48,7 +48,7 @@
36.4 import org.netbeans.api.progress.ProgressHandle;
36.5 import org.netbeans.modules.docker.api.DockerException;
36.6 import org.netbeans.modules.docker.api.DockerAction;
36.7 -import org.netbeans.modules.docker.ui.node.EnhancedDockerContainer;
36.8 +import org.netbeans.modules.docker.ui.node.StatefulDockerContainer;
36.9 import org.openide.DialogDescriptor;
36.10 import org.openide.DialogDisplayer;
36.11 import org.openide.NotifyDescriptor;
36.12 @@ -74,7 +74,7 @@
36.13 })
36.14 @Override
36.15 protected void performAction(Node[] activatedNodes) {
36.16 - EnhancedDockerContainer container = activatedNodes[0].getLookup().lookup(EnhancedDockerContainer.class);
36.17 + StatefulDockerContainer container = activatedNodes[0].getLookup().lookup(StatefulDockerContainer.class);
36.18 if (container != null) {
36.19 JButton renameButton = new JButton();
36.20 Mnemonics.setLocalizedText(renameButton, Bundle.LBL_Rename());
36.21 @@ -107,7 +107,7 @@
36.22 "# {0} - container name",
36.23 "MSG_Renaming=Renaming {0}"
36.24 })
36.25 - private void perform(final EnhancedDockerContainer container, final String name) {
36.26 + private void perform(final StatefulDockerContainer container, final String name) {
36.27 RequestProcessor.getDefault().post(new Runnable() {
36.28 @Override
36.29 public void run() {
36.30 @@ -133,7 +133,7 @@
36.31 if (activatedNodes.length != 1) {
36.32 return false;
36.33 }
36.34 - return activatedNodes[0].getLookup().lookup(EnhancedDockerContainer.class) != null;
36.35 + return activatedNodes[0].getLookup().lookup(StatefulDockerContainer.class) != null;
36.36 }
36.37
36.38 @NbBundle.Messages("LBL_RenameContainerAction=Rename...")
37.1 --- a/docker.ui/src/org/netbeans/modules/docker/ui/wizard/AddDockerInstanceWizard.java Wed Mar 23 21:02:01 2016 +0000
37.2 +++ b/docker.ui/src/org/netbeans/modules/docker/ui/wizard/AddDockerInstanceWizard.java Thu Mar 24 15:34:03 2016 +0100
37.3 @@ -42,15 +42,19 @@
37.4 package org.netbeans.modules.docker.ui.wizard;
37.5
37.6 import java.io.File;
37.7 +import java.net.MalformedURLException;
37.8 import java.text.MessageFormat;
37.9 import java.util.ArrayList;
37.10 import java.util.List;
37.11 +import java.util.logging.Level;
37.12 +import java.util.logging.Logger;
37.13 import javax.swing.JComponent;
37.14 import org.netbeans.modules.docker.api.DockerInstance;
37.15 -import org.netbeans.modules.docker.api.DockerIntegration;
37.16 +import org.netbeans.modules.docker.api.DockerSupport;
37.17 import org.openide.DialogDisplayer;
37.18 import org.openide.WizardDescriptor;
37.19 import org.openide.util.NbBundle;
37.20 +import org.openide.util.Utilities;
37.21
37.22 /**
37.23 *
37.24 @@ -60,6 +64,10 @@
37.25
37.26 public static final String DISPLAY_NAME_PROPERTY = "displayName";
37.27
37.28 + public static final String SOCKET_SELECTED_PROPERTY = "socketSelected";
37.29 +
37.30 + public static final String SOCKET_PROPERTY = "socket";
37.31 +
37.32 public static final String URL_PROPERTY = "url";
37.33
37.34 public static final String CERTIFICATE_PATH_PROPERTY = "certPath";
37.35 @@ -70,6 +78,8 @@
37.36
37.37 public static final String DEFAULT_KEY_FILE = "key.pem";
37.38
37.39 + private static final Logger LOGGER = Logger.getLogger(AddDockerInstanceWizard.class.getName());
37.40 +
37.41 @NbBundle.Messages("LBL_AddDockerInstance=Add Docker Instance")
37.42 public DockerInstance show() {
37.43 List<WizardDescriptor.Panel<WizardDescriptor>> panels = new ArrayList<>();
37.44 @@ -91,20 +101,37 @@
37.45 wiz.setTitle(Bundle.LBL_AddDockerInstance());
37.46 if (DialogDisplayer.getDefault().notify(wiz) == WizardDescriptor.FINISH_OPTION) {
37.47
37.48 - File caFile = null;
37.49 - File certFile = null;
37.50 - File keyFile = null;
37.51 + Boolean socketSelected = (Boolean) wiz.getProperty(SOCKET_SELECTED_PROPERTY);
37.52 + if (socketSelected) {
37.53 + File file = (File) wiz.getProperty(SOCKET_PROPERTY);
37.54 + try {
37.55 + DockerInstance instance = DockerInstance.getInstance(
37.56 + Utilities.toURI(file).toURL().toString(),
37.57 + (String) wiz.getProperty(DISPLAY_NAME_PROPERTY),
37.58 + null, null, null);
37.59 + return DockerSupport.getDefault().addInstance(instance);
37.60 + } catch (MalformedURLException ex) {
37.61 + LOGGER.log(Level.WARNING, null, ex);
37.62 + }
37.63 + } else {
37.64 + File caFile = null;
37.65 + File certFile = null;
37.66 + File keyFile = null;
37.67
37.68 - String strCertPath = (String) wiz.getProperty(CERTIFICATE_PATH_PROPERTY);
37.69 - if (strCertPath != null) {
37.70 - File file = new File(strCertPath);
37.71 - caFile = new File(file, DEFAULT_CA_FILE);
37.72 - certFile = new File(file, DEFAULT_CERT_FILE);
37.73 - keyFile = new File(file, DEFAULT_KEY_FILE);
37.74 + String strCertPath = (String) wiz.getProperty(CERTIFICATE_PATH_PROPERTY);
37.75 + if (strCertPath != null) {
37.76 + File file = new File(strCertPath);
37.77 + caFile = new File(file, DEFAULT_CA_FILE);
37.78 + certFile = new File(file, DEFAULT_CERT_FILE);
37.79 + keyFile = new File(file, DEFAULT_KEY_FILE);
37.80 + }
37.81 +
37.82 + DockerInstance instance = DockerInstance.getInstance(
37.83 + (String) wiz.getProperty(URL_PROPERTY),
37.84 + (String) wiz.getProperty(DISPLAY_NAME_PROPERTY),
37.85 + caFile, certFile, keyFile);
37.86 + return DockerSupport.getDefault().addInstance(instance);
37.87 }
37.88 -
37.89 - return DockerIntegration.getDefault().createInstance((String) wiz.getProperty(DISPLAY_NAME_PROPERTY),
37.90 - (String) wiz.getProperty(URL_PROPERTY), caFile, certFile, keyFile);
37.91 }
37.92 return null;
37.93 }
38.1 --- a/docker.ui/src/org/netbeans/modules/docker/ui/wizard/Bundle.properties Wed Mar 23 21:02:01 2016 +0000
38.2 +++ b/docker.ui/src/org/netbeans/modules/docker/ui/wizard/Bundle.properties Thu Mar 24 15:34:03 2016 +0100
38.3 @@ -1,7 +1,15 @@
38.4
38.5 LBL_AddDockerInstanceAction=Add Docker...
38.6 -DockerConnectionVisual.browseButton.text=&Browse...
38.7 -DockerConnectionVisual.certDirectoryLabel.text=&Cerificates Path:
38.8 -DockerConnectionVisual.nameLabel.text=&Name:
38.9 -DockerConnectionVisual.explanationLabel.text=<html>The docker deamon must be configured to listen on TCP socket. You can do so by starting it with -H tcp://127.0.0.1:2375. See the Docker documentation for reference.</html>
38.10 -DockerConnectionVisual.urlLabel.text=&URL:
38.11 +ConfigurationPanel.nameLabel.text=&Name:
38.12 +ConfigurationPanel.browseButton.text=&Browse...
38.13 +ConfigurationPanel.certDirectoryLabel.text=&Cerificates Path:
38.14 +ConfigurationPanel.urlLabel.text=&URL:
38.15 +ConfigurationLinuxPanel.nameLabel.text=&Name:
38.16 +ConfigurationLinuxPanel.certDirectoryLabel.text=&Cerificates Path:
38.17 +ConfigurationLinuxPanel.urlLabel.text=&URL:
38.18 +ConfigurationLinuxPanel.socketBrowseButton.text=B&rowse...
38.19 +ConfigurationLinuxPanel.socketLabel.text=&Socket:
38.20 +ConfigurationLinuxPanel.socketRadioButton.text=&Unix Socket:
38.21 +ConfigurationLinuxPanel.urlRadioButton.text=&TCP Connection
38.22 +ConfigurationLinuxPanel.certBrowseButton.text=&Browse...
38.23 +DockerConnectionVisual.testButton.text=&Test Connection
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
39.2 +++ b/docker.ui/src/org/netbeans/modules/docker/ui/wizard/Configuration.java Thu Mar 24 15:34:03 2016 +0100
39.3 @@ -0,0 +1,76 @@
39.4 +/*
39.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
39.6 + *
39.7 + * Copyright 2016 Oracle and/or its affiliates. All rights reserved.
39.8 + *
39.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
39.10 + * Other names may be trademarks of their respective owners.
39.11 + *
39.12 + * The contents of this file are subject to the terms of either the GNU
39.13 + * General Public License Version 2 only ("GPL") or the Common
39.14 + * Development and Distribution License("CDDL") (collectively, the
39.15 + * "License"). You may not use this file except in compliance with the
39.16 + * License. You can obtain a copy of the License at
39.17 + * http://www.netbeans.org/cddl-gplv2.html
39.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
39.19 + * specific language governing permissions and limitations under the
39.20 + * License. When distributing the software, include this License Header
39.21 + * Notice in each file and include the License file at
39.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
39.23 + * particular file as subject to the "Classpath" exception as provided
39.24 + * by Oracle in the GPL Version 2 section of the License file that
39.25 + * accompanied this code. If applicable, add the following below the
39.26 + * License Header, with the fields enclosed by brackets [] replaced by
39.27 + * your own identifying information:
39.28 + * "Portions Copyrighted [year] [name of copyright owner]"
39.29 + *
39.30 + * If you wish your version of this file to be governed by only the CDDL
39.31 + * or only the GPL Version 2, indicate your decision by adding
39.32 + * "[Contributor] elects to include this software in this distribution
39.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
39.34 + * single choice of license, a recipient has the option to distribute
39.35 + * your version of this file under either the CDDL, the GPL Version 2 or
39.36 + * to extend the choice of license to its licensees as provided above.
39.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
39.38 + * Version 2 license, then the option applies only if the new code is
39.39 + * made subject to such option by the copyright holder.
39.40 + *
39.41 + * Contributor(s):
39.42 + *
39.43 + * Portions Copyrighted 2016 Sun Microsystems, Inc.
39.44 + */
39.45 +package org.netbeans.modules.docker.ui.wizard;
39.46 +
39.47 +import java.io.File;
39.48 +import javax.swing.event.ChangeListener;
39.49 +
39.50 +/**
39.51 + *
39.52 + * @author Petr Hejl
39.53 + */
39.54 +public interface Configuration {
39.55 +
39.56 + void addChangeListener(ChangeListener l);
39.57 +
39.58 + void removeChangeListener(ChangeListener l);
39.59 +
39.60 + String getDisplayName();
39.61 +
39.62 + void setDisplayName(String displayName);
39.63 +
39.64 + boolean isSocketSelected();
39.65 +
39.66 + void setSocketSelected(boolean socketSelected);
39.67 +
39.68 + File getSocket();
39.69 +
39.70 + void setSocket(File socket);
39.71 +
39.72 + String getUrl();
39.73 +
39.74 + void setUrl(String url);
39.75 +
39.76 + String getCertPath();
39.77 +
39.78 + void setCertPath(String path);
39.79 +}
40.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
40.2 +++ b/docker.ui/src/org/netbeans/modules/docker/ui/wizard/ConfigurationLinuxPanel.form Thu Mar 24 15:34:03 2016 +0100
40.3 @@ -0,0 +1,180 @@
40.4 +<?xml version="1.0" encoding="UTF-8" ?>
40.5 +
40.6 +<Form version="1.4" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
40.7 + <NonVisualComponents>
40.8 + <Component class="javax.swing.ButtonGroup" name="switchButtonGroup">
40.9 + </Component>
40.10 + </NonVisualComponents>
40.11 + <AuxValues>
40.12 + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
40.13 + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
40.14 + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
40.15 + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
40.16 + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
40.17 + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
40.18 + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
40.19 + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
40.20 + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
40.21 + </AuxValues>
40.22 +
40.23 + <Layout>
40.24 + <DimensionLayout dim="0">
40.25 + <Group type="103" groupAlignment="0" attributes="0">
40.26 + <Group type="102" attributes="0">
40.27 + <Component id="nameLabel" min="-2" max="-2" attributes="0"/>
40.28 + <EmptySpace max="-2" attributes="0"/>
40.29 + <Component id="nameTextField" max="32767" attributes="0"/>
40.30 + </Group>
40.31 + <Group type="102" attributes="0">
40.32 + <Component id="socketRadioButton" min="-2" max="-2" attributes="0"/>
40.33 + <EmptySpace max="32767" attributes="0"/>
40.34 + </Group>
40.35 + <Group type="102" attributes="0">
40.36 + <Component id="urlRadioButton" min="-2" max="-2" attributes="0"/>
40.37 + <EmptySpace min="0" pref="0" max="32767" attributes="0"/>
40.38 + </Group>
40.39 + <Group type="102" alignment="0" attributes="0">
40.40 + <EmptySpace max="-2" attributes="0"/>
40.41 + <Group type="103" groupAlignment="0" attributes="0">
40.42 + <Component id="socketLabel" alignment="0" min="-2" max="-2" attributes="0"/>
40.43 + <Component id="urlLabel" alignment="0" min="-2" max="-2" attributes="0"/>
40.44 + <Component id="certDirectoryLabel" alignment="0" min="-2" max="-2" attributes="0"/>
40.45 + </Group>
40.46 + <EmptySpace max="-2" attributes="0"/>
40.47 + <Group type="103" groupAlignment="0" attributes="0">
40.48 + <Group type="102" alignment="0" attributes="0">
40.49 + <Component id="socketTextField" pref="190" max="32767" attributes="0"/>
40.50 + <EmptySpace max="-2" attributes="0"/>
40.51 + <Component id="socketBrowseButton" min="-2" max="-2" attributes="0"/>
40.52 + </Group>
40.53 + <Group type="102" alignment="0" attributes="0">
40.54 + <Component id="certTextField" max="32767" attributes="0"/>
40.55 + <EmptySpace max="-2" attributes="0"/>
40.56 + <Component id="certBrowseButton" min="-2" max="-2" attributes="0"/>
40.57 + </Group>
40.58 + <Component id="urlTextField" alignment="0" max="32767" attributes="0"/>
40.59 + </Group>
40.60 + </Group>
40.61 + </Group>
40.62 + </DimensionLayout>
40.63 + <DimensionLayout dim="1">
40.64 + <Group type="103" groupAlignment="0" attributes="0">
40.65 + <Group type="102" alignment="0" attributes="0">
40.66 + <Group type="103" groupAlignment="3" attributes="0">
40.67 + <Component id="nameLabel" alignment="3" min="-2" max="-2" attributes="0"/>
40.68 + <Component id="nameTextField" alignment="3" min="-2" max="-2" attributes="0"/>
40.69 + </Group>
40.70 + <EmptySpace max="-2" attributes="0"/>
40.71 + <Component id="socketRadioButton" min="-2" max="-2" attributes="0"/>
40.72 + <EmptySpace max="-2" attributes="0"/>
40.73 + <Group type="103" groupAlignment="3" attributes="0">
40.74 + <Component id="socketLabel" alignment="3" min="-2" max="-2" attributes="0"/>
40.75 + <Component id="socketTextField" alignment="3" min="-2" max="-2" attributes="0"/>
40.76 + <Component id="socketBrowseButton" alignment="3" min="-2" max="-2" attributes="0"/>
40.77 + </Group>
40.78 + <EmptySpace max="-2" attributes="0"/>
40.79 + <Component id="urlRadioButton" min="-2" max="-2" attributes="0"/>
40.80 + <EmptySpace max="-2" attributes="0"/>
40.81 + <Group type="103" groupAlignment="3" attributes="0">
40.82 + <Component id="urlLabel" alignment="3" min="-2" max="-2" attributes="0"/>
40.83 + <Component id="urlTextField" alignment="3" min="-2" max="-2" attributes="0"/>
40.84 + </Group>
40.85 + <EmptySpace max="-2" attributes="0"/>
40.86 + <Group type="103" groupAlignment="3" attributes="0">
40.87 + <Component id="certDirectoryLabel" alignment="3" min="-2" max="-2" attributes="0"/>
40.88 + <Component id="certTextField" alignment="3" min="-2" max="-2" attributes="0"/>
40.89 + <Component id="certBrowseButton" alignment="3" min="-2" max="-2" attributes="0"/>
40.90 + </Group>
40.91 + </Group>
40.92 + </Group>
40.93 + </DimensionLayout>
40.94 + </Layout>
40.95 + <SubComponents>
40.96 + <Component class="javax.swing.JLabel" name="nameLabel">
40.97 + <Properties>
40.98 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
40.99 + <ResourceString bundle="org/netbeans/modules/docker/ui/wizard/Bundle.properties" key="ConfigurationLinuxPanel.nameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
40.100 + </Property>
40.101 + </Properties>
40.102 + </Component>
40.103 + <Component class="javax.swing.JTextField" name="nameTextField">
40.104 + </Component>
40.105 + <Component class="javax.swing.JLabel" name="urlLabel">
40.106 + <Properties>
40.107 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
40.108 + <ResourceString bundle="org/netbeans/modules/docker/ui/wizard/Bundle.properties" key="ConfigurationLinuxPanel.urlLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
40.109 + </Property>
40.110 + </Properties>
40.111 + </Component>
40.112 + <Component class="javax.swing.JTextField" name="urlTextField">
40.113 + </Component>
40.114 + <Component class="javax.swing.JLabel" name="certDirectoryLabel">
40.115 + <Properties>
40.116 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
40.117 + <ResourceString bundle="org/netbeans/modules/docker/ui/wizard/Bundle.properties" key="ConfigurationLinuxPanel.certDirectoryLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
40.118 + </Property>
40.119 + </Properties>
40.120 + </Component>
40.121 + <Component class="javax.swing.JTextField" name="certTextField">
40.122 + </Component>
40.123 + <Component class="javax.swing.JButton" name="certBrowseButton">
40.124 + <Properties>
40.125 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
40.126 + <ResourceString bundle="org/netbeans/modules/docker/ui/wizard/Bundle.properties" key="ConfigurationLinuxPanel.certBrowseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
40.127 + </Property>
40.128 + </Properties>
40.129 + <Events>
40.130 + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="certBrowseButtonActionPerformed"/>
40.131 + </Events>
40.132 + </Component>
40.133 + <Component class="javax.swing.JRadioButton" name="socketRadioButton">
40.134 + <Properties>
40.135 + <Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
40.136 + <ComponentRef name="switchButtonGroup"/>
40.137 + </Property>
40.138 + <Property name="selected" type="boolean" value="true"/>
40.139 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
40.140 + <ResourceString bundle="org/netbeans/modules/docker/ui/wizard/Bundle.properties" key="ConfigurationLinuxPanel.socketRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
40.141 + </Property>
40.142 + </Properties>
40.143 + <Events>
40.144 + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="socketRadioButtonActionPerformed"/>
40.145 + </Events>
40.146 + </Component>
40.147 + <Component class="javax.swing.JLabel" name="socketLabel">
40.148 + <Properties>
40.149 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
40.150 + <ComponentRef name="socketTextField"/>
40.151 + </Property>
40.152 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
40.153 + <ResourceString bundle="org/netbeans/modules/docker/ui/wizard/Bundle.properties" key="ConfigurationLinuxPanel.socketLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
40.154 + </Property>
40.155 + </Properties>
40.156 + </Component>
40.157 + <Component class="javax.swing.JButton" name="socketBrowseButton">
40.158 + <Properties>
40.159 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
40.160 + <ResourceString bundle="org/netbeans/modules/docker/ui/wizard/Bundle.properties" key="ConfigurationLinuxPanel.socketBrowseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
40.161 + </Property>
40.162 + </Properties>
40.163 + <Events>
40.164 + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="socketBrowseButtonActionPerformed"/>
40.165 + </Events>
40.166 + </Component>
40.167 + <Component class="javax.swing.JTextField" name="socketTextField">
40.168 + </Component>
40.169 + <Component class="javax.swing.JRadioButton" name="urlRadioButton">
40.170 + <Properties>
40.171 + <Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
40.172 + <ComponentRef name="switchButtonGroup"/>
40.173 + </Property>
40.174 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
40.175 + <ResourceString bundle="org/netbeans/modules/docker/ui/wizard/Bundle.properties" key="ConfigurationLinuxPanel.urlRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
40.176 + </Property>
40.177 + </Properties>
40.178 + <Events>
40.179 + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="urlRadioButtonActionPerformed"/>
40.180 + </Events>
40.181 + </Component>
40.182 + </SubComponents>
40.183 +</Form>
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
41.2 +++ b/docker.ui/src/org/netbeans/modules/docker/ui/wizard/ConfigurationLinuxPanel.java Thu Mar 24 15:34:03 2016 +0100
41.3 @@ -0,0 +1,342 @@
41.4 +/*
41.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
41.6 + *
41.7 + * Copyright 2016 Oracle and/or its affiliates. All rights reserved.
41.8 + *
41.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
41.10 + * Other names may be trademarks of their respective owners.
41.11 + *
41.12 + * The contents of this file are subject to the terms of either the GNU
41.13 + * General Public License Version 2 only ("GPL") or the Common
41.14 + * Development and Distribution License("CDDL") (collectively, the
41.15 + * "License"). You may not use this file except in compliance with the
41.16 + * License. You can obtain a copy of the License at
41.17 + * http://www.netbeans.org/cddl-gplv2.html
41.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
41.19 + * specific language governing permissions and limitations under the
41.20 + * License. When distributing the software, include this License Header
41.21 + * Notice in each file and include the License file at
41.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
41.23 + * particular file as subject to the "Classpath" exception as provided
41.24 + * by Oracle in the GPL Version 2 section of the License file that
41.25 + * accompanied this code. If applicable, add the following below the
41.26 + * License Header, with the fields enclosed by brackets [] replaced by
41.27 + * your own identifying information:
41.28 + * "Portions Copyrighted [year] [name of copyright owner]"
41.29 + *
41.30 + * If you wish your version of this file to be governed by only the CDDL
41.31 + * or only the GPL Version 2, indicate your decision by adding
41.32 + * "[Contributor] elects to include this software in this distribution
41.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
41.34 + * single choice of license, a recipient has the option to distribute
41.35 + * your version of this file under either the CDDL, the GPL Version 2 or
41.36 + * to extend the choice of license to its licensees as provided above.
41.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
41.38 + * Version 2 license, then the option applies only if the new code is
41.39 + * made subject to such option by the copyright holder.
41.40 + *
41.41 + * Contributor(s):
41.42 + *
41.43 + * Portions Copyrighted 2016 Sun Microsystems, Inc.
41.44 + */
41.45 +package org.netbeans.modules.docker.ui.wizard;
41.46 +
41.47 +import java.io.File;
41.48 +import javax.swing.JFileChooser;
41.49 +import javax.swing.SwingUtilities;
41.50 +import javax.swing.event.ChangeListener;
41.51 +import javax.swing.event.DocumentEvent;
41.52 +import javax.swing.event.DocumentListener;
41.53 +import org.netbeans.modules.docker.ui.UiUtils;
41.54 +import org.openide.util.ChangeSupport;
41.55 +
41.56 +/**
41.57 + *
41.58 + * @author Petr Hejl
41.59 + */
41.60 +public class ConfigurationLinuxPanel extends javax.swing.JPanel implements Configuration {
41.61 +
41.62 + private final ChangeSupport changeSupport = new ChangeSupport(this);
41.63 +
41.64 + /**
41.65 + * Creates new form DockerConnectionLinux
41.66 + */
41.67 + public ConfigurationLinuxPanel() {
41.68 + initComponents();
41.69 +
41.70 + DefaultDocumentListener listener = new DefaultDocumentListener();
41.71 + nameTextField.getDocument().addDocumentListener(listener);
41.72 + socketTextField.getDocument().addDocumentListener(listener);
41.73 + urlTextField.getDocument().addDocumentListener(listener);
41.74 + certTextField.getDocument().addDocumentListener(listener);
41.75 + }
41.76 +
41.77 + @Override
41.78 + public void addChangeListener(ChangeListener l) {
41.79 + changeSupport.addChangeListener(l);
41.80 + }
41.81 +
41.82 + @Override
41.83 + public void removeChangeListener(ChangeListener l) {
41.84 + changeSupport.removeChangeListener(l);
41.85 + }
41.86 +
41.87 + @Override
41.88 + public String getDisplayName() {
41.89 + return UiUtils.getValue(nameTextField);
41.90 + }
41.91 +
41.92 + @Override
41.93 + public void setDisplayName(String displayName) {
41.94 + nameTextField.setText(displayName);
41.95 + }
41.96 +
41.97 + @Override
41.98 + public boolean isSocketSelected() {
41.99 + return socketRadioButton.isSelected();
41.100 + }
41.101 +
41.102 + @Override
41.103 + public void setSocketSelected(boolean socketSelected) {
41.104 + socketRadioButton.setSelected(socketSelected);
41.105 + refresh();
41.106 + }
41.107 +
41.108 + @Override
41.109 + public File getSocket() {
41.110 + String value = UiUtils.getValue(socketTextField);
41.111 + if (value != null) {
41.112 + return new File(value);
41.113 + }
41.114 + return null;
41.115 + }
41.116 +
41.117 + @Override
41.118 + public void setSocket(File socket) {
41.119 + if (socket != null) {
41.120 + socketTextField.setText(socket.getAbsolutePath());
41.121 + }
41.122 + }
41.123 +
41.124 + @Override
41.125 + public String getUrl() {
41.126 + return UiUtils.getValue(urlTextField);
41.127 + }
41.128 +
41.129 + @Override
41.130 + public void setUrl(String url) {
41.131 + urlTextField.setText(url);
41.132 + }
41.133 +
41.134 + @Override
41.135 + public String getCertPath() {
41.136 + return UiUtils.getValue(certTextField);
41.137 + }
41.138 +
41.139 + @Override
41.140 + public void setCertPath(String path) {
41.141 + certTextField.setText(path);
41.142 + }
41.143 +
41.144 + private void refresh() {
41.145 + boolean socketSelected = socketRadioButton.isSelected();
41.146 + socketTextField.setEnabled(socketSelected);
41.147 + socketBrowseButton.setEnabled(socketSelected);
41.148 + urlTextField.setEnabled(!socketSelected);
41.149 + certTextField.setEnabled(!socketSelected);
41.150 + certBrowseButton.setEnabled(!socketSelected);
41.151 +
41.152 + changeSupport.fireChange();
41.153 + }
41.154 +
41.155 + private class DefaultDocumentListener implements DocumentListener {
41.156 +
41.157 + @Override
41.158 + public void insertUpdate(DocumentEvent e) {
41.159 + changeSupport.fireChange();
41.160 + }
41.161 +
41.162 + @Override
41.163 + public void removeUpdate(DocumentEvent e) {
41.164 + changeSupport.fireChange();
41.165 + }
41.166 +
41.167 + @Override
41.168 + public void changedUpdate(DocumentEvent e) {
41.169 + changeSupport.fireChange();
41.170 + }
41.171 + }
41.172 +
41.173 + /**
41.174 + * This method is called from within the constructor to initialize the form.
41.175 + * WARNING: Do NOT modify this code. The content of this method is always
41.176 + * regenerated by the Form Editor.
41.177 + */
41.178 + @SuppressWarnings("unchecked")
41.179 + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
41.180 + private void initComponents() {
41.181 +
41.182 + switchButtonGroup = new javax.swing.ButtonGroup();
41.183 + nameLabel = new javax.swing.JLabel();
41.184 + nameTextField = new javax.swing.JTextField();
41.185 + urlLabel = new javax.swing.JLabel();
41.186 + urlTextField = new javax.swing.JTextField();
41.187 + certDirectoryLabel = new javax.swing.JLabel();
41.188 + certTextField = new javax.swing.JTextField();
41.189 + certBrowseButton = new javax.swing.JButton();
41.190 + socketRadioButton = new javax.swing.JRadioButton();
41.191 + socketLabel = new javax.swing.JLabel();
41.192 + socketBrowseButton = new javax.swing.JButton();
41.193 + socketTextField = new javax.swing.JTextField();
41.194 + urlRadioButton = new javax.swing.JRadioButton();
41.195 +
41.196 + org.openide.awt.Mnemonics.setLocalizedText(nameLabel, org.openide.util.NbBundle.getMessage(ConfigurationLinuxPanel.class, "ConfigurationLinuxPanel.nameLabel.text")); // NOI18N
41.197 +
41.198 + org.openide.awt.Mnemonics.setLocalizedText(urlLabel, org.openide.util.NbBundle.getMessage(ConfigurationLinuxPanel.class, "ConfigurationLinuxPanel.urlLabel.text")); // NOI18N
41.199 +
41.200 + org.openide.awt.Mnemonics.setLocalizedText(certDirectoryLabel, org.openide.util.NbBundle.getMessage(ConfigurationLinuxPanel.class, "ConfigurationLinuxPanel.certDirectoryLabel.text")); // NOI18N
41.201 +
41.202 + org.openide.awt.Mnemonics.setLocalizedText(certBrowseButton, org.openide.util.NbBundle.getMessage(ConfigurationLinuxPanel.class, "ConfigurationLinuxPanel.certBrowseButton.text")); // NOI18N
41.203 + certBrowseButton.addActionListener(new java.awt.event.ActionListener() {
41.204 + public void actionPerformed(java.awt.event.ActionEvent evt) {
41.205 + certBrowseButtonActionPerformed(evt);
41.206 + }
41.207 + });
41.208 +
41.209 + switchButtonGroup.add(socketRadioButton);
41.210 + socketRadioButton.setSelected(true);
41.211 + org.openide.awt.Mnemonics.setLocalizedText(socketRadioButton, org.openide.util.NbBundle.getMessage(ConfigurationLinuxPanel.class, "ConfigurationLinuxPanel.socketRadioButton.text")); // NOI18N
41.212 + socketRadioButton.addActionListener(new java.awt.event.ActionListener() {
41.213 + public void actionPerformed(java.awt.event.ActionEvent evt) {
41.214 + socketRadioButtonActionPerformed(evt);
41.215 + }
41.216 + });
41.217 +
41.218 + socketLabel.setLabelFor(socketTextField);
41.219 + org.openide.awt.Mnemonics.setLocalizedText(socketLabel, org.openide.util.NbBundle.getMessage(ConfigurationLinuxPanel.class, "ConfigurationLinuxPanel.socketLabel.text")); // NOI18N
41.220 +
41.221 + org.openide.awt.Mnemonics.setLocalizedText(socketBrowseButton, org.openide.util.NbBundle.getMessage(ConfigurationLinuxPanel.class, "ConfigurationLinuxPanel.socketBrowseButton.text")); // NOI18N
41.222 + socketBrowseButton.addActionListener(new java.awt.event.ActionListener() {
41.223 + public void actionPerformed(java.awt.event.ActionEvent evt) {
41.224 + socketBrowseButtonActionPerformed(evt);
41.225 + }
41.226 + });
41.227 +
41.228 + switchButtonGroup.add(urlRadioButton);
41.229 + org.openide.awt.Mnemonics.setLocalizedText(urlRadioButton, org.openide.util.NbBundle.getMessage(ConfigurationLinuxPanel.class, "ConfigurationLinuxPanel.urlRadioButton.text")); // NOI18N
41.230 + urlRadioButton.addActionListener(new java.awt.event.ActionListener() {
41.231 + public void actionPerformed(java.awt.event.ActionEvent evt) {
41.232 + urlRadioButtonActionPerformed(evt);
41.233 + }
41.234 + });
41.235 +
41.236 + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
41.237 + this.setLayout(layout);
41.238 + layout.setHorizontalGroup(
41.239 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
41.240 + .addGroup(layout.createSequentialGroup()
41.241 + .addComponent(nameLabel)
41.242 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
41.243 + .addComponent(nameTextField))
41.244 + .addGroup(layout.createSequentialGroup()
41.245 + .addComponent(socketRadioButton)
41.246 + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
41.247 + .addGroup(layout.createSequentialGroup()
41.248 + .addComponent(urlRadioButton)
41.249 + .addGap(0, 0, Short.MAX_VALUE))
41.250 + .addGroup(layout.createSequentialGroup()
41.251 + .addContainerGap()
41.252 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
41.253 + .addComponent(socketLabel)
41.254 + .addComponent(urlLabel)
41.255 + .addComponent(certDirectoryLabel))
41.256 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
41.257 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
41.258 + .addGroup(layout.createSequentialGroup()
41.259 + .addComponent(socketTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 190, Short.MAX_VALUE)
41.260 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
41.261 + .addComponent(socketBrowseButton))
41.262 + .addGroup(layout.createSequentialGroup()
41.263 + .addComponent(certTextField)
41.264 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
41.265 + .addComponent(certBrowseButton))
41.266 + .addComponent(urlTextField)))
41.267 + );
41.268 + layout.setVerticalGroup(
41.269 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
41.270 + .addGroup(layout.createSequentialGroup()
41.271 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
41.272 + .addComponent(nameLabel)
41.273 + .addComponent(nameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
41.274 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
41.275 + .addComponent(socketRadioButton)
41.276 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
41.277 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
41.278 + .addComponent(socketLabel)
41.279 + .addComponent(socketTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
41.280 + .addComponent(socketBrowseButton))
41.281 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
41.282 + .addComponent(urlRadioButton)
41.283 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
41.284 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
41.285 + .addComponent(urlLabel)
41.286 + .addComponent(urlTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
41.287 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
41.288 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
41.289 + .addComponent(certDirectoryLabel)
41.290 + .addComponent(certTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
41.291 + .addComponent(certBrowseButton)))
41.292 + );
41.293 + }// </editor-fold>//GEN-END:initComponents
41.294 +
41.295 + private void certBrowseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_certBrowseButtonActionPerformed
41.296 + JFileChooser chooser = new JFileChooser();
41.297 + chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
41.298 + chooser.setFileHidingEnabled(false);
41.299 + String text = UiUtils.getValue(certTextField);
41.300 + if (text != null) {
41.301 + chooser.setSelectedFile(new File(text));
41.302 + }
41.303 + if (chooser.showOpenDialog(SwingUtilities.getWindowAncestor(this)) == JFileChooser.APPROVE_OPTION) {
41.304 + certTextField.setText(chooser.getSelectedFile().getAbsolutePath());
41.305 + }
41.306 + }//GEN-LAST:event_certBrowseButtonActionPerformed
41.307 +
41.308 + private void socketBrowseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_socketBrowseButtonActionPerformed
41.309 + JFileChooser chooser = new JFileChooser();
41.310 + chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
41.311 + chooser.setFileHidingEnabled(false);
41.312 + String text = UiUtils.getValue(socketTextField);
41.313 + if (text != null) {
41.314 + chooser.setSelectedFile(new File(text));
41.315 + }
41.316 + if (chooser.showOpenDialog(SwingUtilities.getWindowAncestor(this)) == JFileChooser.APPROVE_OPTION) {
41.317 + socketTextField.setText(chooser.getSelectedFile().getAbsolutePath());
41.318 + }
41.319 + }//GEN-LAST:event_socketBrowseButtonActionPerformed
41.320 +
41.321 + private void socketRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_socketRadioButtonActionPerformed
41.322 + refresh();
41.323 + }//GEN-LAST:event_socketRadioButtonActionPerformed
41.324 +
41.325 + private void urlRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_urlRadioButtonActionPerformed
41.326 + refresh();
41.327 + }//GEN-LAST:event_urlRadioButtonActionPerformed
41.328 +
41.329 +
41.330 + // Variables declaration - do not modify//GEN-BEGIN:variables
41.331 + private javax.swing.JButton certBrowseButton;
41.332 + private javax.swing.JLabel certDirectoryLabel;
41.333 + private javax.swing.JTextField certTextField;
41.334 + private javax.swing.JLabel nameLabel;
41.335 + private javax.swing.JTextField nameTextField;
41.336 + private javax.swing.JButton socketBrowseButton;
41.337 + private javax.swing.JLabel socketLabel;
41.338 + private javax.swing.JRadioButton socketRadioButton;
41.339 + private javax.swing.JTextField socketTextField;
41.340 + private javax.swing.ButtonGroup switchButtonGroup;
41.341 + private javax.swing.JLabel urlLabel;
41.342 + private javax.swing.JRadioButton urlRadioButton;
41.343 + private javax.swing.JTextField urlTextField;
41.344 + // End of variables declaration//GEN-END:variables
41.345 +}
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
42.2 +++ b/docker.ui/src/org/netbeans/modules/docker/ui/wizard/ConfigurationPanel.form Thu Mar 24 15:34:03 2016 +0100
42.3 @@ -0,0 +1,99 @@
42.4 +<?xml version="1.0" encoding="UTF-8" ?>
42.5 +
42.6 +<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
42.7 + <AuxValues>
42.8 + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
42.9 + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
42.10 + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
42.11 + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
42.12 + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
42.13 + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
42.14 + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
42.15 + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
42.16 + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
42.17 + </AuxValues>
42.18 +
42.19 + <Layout>
42.20 + <DimensionLayout dim="0">
42.21 + <Group type="103" groupAlignment="0" attributes="0">
42.22 + <Group type="102" alignment="0" attributes="0">
42.23 + <Group type="103" groupAlignment="0" attributes="0">
42.24 + <Component id="certDirectoryLabel" alignment="0" min="-2" max="-2" attributes="0"/>
42.25 + <Component id="urlLabel" alignment="0" min="-2" max="-2" attributes="0"/>
42.26 + <Component id="nameLabel" alignment="0" min="-2" max="-2" attributes="0"/>
42.27 + </Group>
42.28 + <EmptySpace max="-2" attributes="0"/>
42.29 + <Group type="103" groupAlignment="0" attributes="0">
42.30 + <Group type="102" alignment="0" attributes="0">
42.31 + <Component id="certTextField" pref="202" max="32767" attributes="0"/>
42.32 + <EmptySpace max="-2" attributes="0"/>
42.33 + <Component id="browseButton" min="-2" max="-2" attributes="0"/>
42.34 + </Group>
42.35 + <Component id="nameTextField" max="32767" attributes="0"/>
42.36 + <Component id="urlTextField" alignment="0" max="32767" attributes="0"/>
42.37 + </Group>
42.38 + </Group>
42.39 + </Group>
42.40 + </DimensionLayout>
42.41 + <DimensionLayout dim="1">
42.42 + <Group type="103" groupAlignment="0" attributes="0">
42.43 + <Group type="102" alignment="0" attributes="0">
42.44 + <Group type="103" groupAlignment="3" attributes="0">
42.45 + <Component id="nameLabel" alignment="3" min="-2" max="-2" attributes="0"/>
42.46 + <Component id="nameTextField" alignment="3" min="-2" max="-2" attributes="0"/>
42.47 + </Group>
42.48 + <EmptySpace max="-2" attributes="0"/>
42.49 + <Group type="103" groupAlignment="3" attributes="0">
42.50 + <Component id="urlLabel" alignment="3" min="-2" max="-2" attributes="0"/>
42.51 + <Component id="urlTextField" alignment="3" min="-2" max="-2" attributes="0"/>
42.52 + </Group>
42.53 + <EmptySpace max="-2" attributes="0"/>
42.54 + <Group type="103" groupAlignment="3" attributes="0">
42.55 + <Component id="certDirectoryLabel" alignment="3" min="-2" max="-2" attributes="0"/>
42.56 + <Component id="certTextField" alignment="3" min="-2" max="-2" attributes="0"/>
42.57 + <Component id="browseButton" alignment="3" min="-2" max="-2" attributes="0"/>
42.58 + </Group>
42.59 + </Group>
42.60 + </Group>
42.61 + </DimensionLayout>
42.62 + </Layout>
42.63 + <SubComponents>
42.64 + <Component class="javax.swing.JLabel" name="nameLabel">
42.65 + <Properties>
42.66 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
42.67 + <ResourceString bundle="org/netbeans/modules/docker/ui/wizard/Bundle.properties" key="ConfigurationPanel.nameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
42.68 + </Property>
42.69 + </Properties>
42.70 + </Component>
42.71 + <Component class="javax.swing.JTextField" name="nameTextField">
42.72 + </Component>
42.73 + <Component class="javax.swing.JLabel" name="urlLabel">
42.74 + <Properties>
42.75 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
42.76 + <ResourceString bundle="org/netbeans/modules/docker/ui/wizard/Bundle.properties" key="ConfigurationPanel.urlLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
42.77 + </Property>
42.78 + </Properties>
42.79 + </Component>
42.80 + <Component class="javax.swing.JTextField" name="urlTextField">
42.81 + </Component>
42.82 + <Component class="javax.swing.JLabel" name="certDirectoryLabel">
42.83 + <Properties>
42.84 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
42.85 + <ResourceString bundle="org/netbeans/modules/docker/ui/wizard/Bundle.properties" key="ConfigurationPanel.certDirectoryLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
42.86 + </Property>
42.87 + </Properties>
42.88 + </Component>
42.89 + <Component class="javax.swing.JTextField" name="certTextField">
42.90 + </Component>
42.91 + <Component class="javax.swing.JButton" name="browseButton">
42.92 + <Properties>
42.93 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
42.94 + <ResourceString bundle="org/netbeans/modules/docker/ui/wizard/Bundle.properties" key="ConfigurationPanel.browseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
42.95 + </Property>
42.96 + </Properties>
42.97 + <Events>
42.98 + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="browseButtonActionPerformed"/>
42.99 + </Events>
42.100 + </Component>
42.101 + </SubComponents>
42.102 +</Form>
43.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
43.2 +++ b/docker.ui/src/org/netbeans/modules/docker/ui/wizard/ConfigurationPanel.java Thu Mar 24 15:34:03 2016 +0100
43.3 @@ -0,0 +1,240 @@
43.4 +/*
43.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
43.6 + *
43.7 + * Copyright 2016 Oracle and/or its affiliates. All rights reserved.
43.8 + *
43.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
43.10 + * Other names may be trademarks of their respective owners.
43.11 + *
43.12 + * The contents of this file are subject to the terms of either the GNU
43.13 + * General Public License Version 2 only ("GPL") or the Common
43.14 + * Development and Distribution License("CDDL") (collectively, the
43.15 + * "License"). You may not use this file except in compliance with the
43.16 + * License. You can obtain a copy of the License at
43.17 + * http://www.netbeans.org/cddl-gplv2.html
43.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
43.19 + * specific language governing permissions and limitations under the
43.20 + * License. When distributing the software, include this License Header
43.21 + * Notice in each file and include the License file at
43.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
43.23 + * particular file as subject to the "Classpath" exception as provided
43.24 + * by Oracle in the GPL Version 2 section of the License file that
43.25 + * accompanied this code. If applicable, add the following below the
43.26 + * License Header, with the fields enclosed by brackets [] replaced by
43.27 + * your own identifying information:
43.28 + * "Portions Copyrighted [year] [name of copyright owner]"
43.29 + *
43.30 + * If you wish your version of this file to be governed by only the CDDL
43.31 + * or only the GPL Version 2, indicate your decision by adding
43.32 + * "[Contributor] elects to include this software in this distribution
43.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
43.34 + * single choice of license, a recipient has the option to distribute
43.35 + * your version of this file under either the CDDL, the GPL Version 2 or
43.36 + * to extend the choice of license to its licensees as provided above.
43.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
43.38 + * Version 2 license, then the option applies only if the new code is
43.39 + * made subject to such option by the copyright holder.
43.40 + *
43.41 + * Contributor(s):
43.42 + *
43.43 + * Portions Copyrighted 2016 Sun Microsystems, Inc.
43.44 + */
43.45 +package org.netbeans.modules.docker.ui.wizard;
43.46 +
43.47 +import java.io.File;
43.48 +import javax.swing.JFileChooser;
43.49 +import javax.swing.SwingUtilities;
43.50 +import javax.swing.event.ChangeListener;
43.51 +import javax.swing.event.DocumentEvent;
43.52 +import javax.swing.event.DocumentListener;
43.53 +import org.netbeans.modules.docker.ui.UiUtils;
43.54 +import org.openide.util.ChangeSupport;
43.55 +
43.56 +/**
43.57 + *
43.58 + * @author Petr Hejl
43.59 + */
43.60 +public class ConfigurationPanel extends javax.swing.JPanel implements Configuration {
43.61 +
43.62 + private final ChangeSupport changeSupport = new ChangeSupport(this);
43.63 +
43.64 + /**
43.65 + * Creates new form DockerConnectionGeneric
43.66 + */
43.67 + public ConfigurationPanel() {
43.68 + initComponents();
43.69 +
43.70 + DefaultDocumentListener listener = new DefaultDocumentListener();
43.71 + nameTextField.getDocument().addDocumentListener(listener);
43.72 + urlTextField.getDocument().addDocumentListener(listener);
43.73 + certTextField.getDocument().addDocumentListener(listener);
43.74 + }
43.75 +
43.76 + @Override
43.77 + public void addChangeListener(ChangeListener l) {
43.78 + changeSupport.addChangeListener(l);
43.79 + }
43.80 +
43.81 + @Override
43.82 + public void removeChangeListener(ChangeListener l) {
43.83 + changeSupport.removeChangeListener(l);
43.84 + }
43.85 +
43.86 + @Override
43.87 + public String getDisplayName() {
43.88 + return UiUtils.getValue(nameTextField);
43.89 + }
43.90 +
43.91 + @Override
43.92 + public void setDisplayName(String displayName) {
43.93 + nameTextField.setText(displayName);
43.94 + }
43.95 +
43.96 + @Override
43.97 + public boolean isSocketSelected() {
43.98 + return false;
43.99 + }
43.100 +
43.101 + @Override
43.102 + public void setSocketSelected(boolean socketSelected) {
43.103 + // noop
43.104 + }
43.105 +
43.106 + @Override
43.107 + public File getSocket() {
43.108 + return null;
43.109 + }
43.110 +
43.111 + @Override
43.112 + public void setSocket(File socket) {
43.113 + // noop
43.114 + }
43.115 +
43.116 + @Override
43.117 + public String getUrl() {
43.118 + return UiUtils.getValue(urlTextField);
43.119 + }
43.120 +
43.121 + @Override
43.122 + public void setUrl(String url) {
43.123 + urlTextField.setText(url);
43.124 + }
43.125 +
43.126 + @Override
43.127 + public String getCertPath() {
43.128 + return UiUtils.getValue(certTextField);
43.129 + }
43.130 +
43.131 + @Override
43.132 + public void setCertPath(String path) {
43.133 + certTextField.setText(path);
43.134 + }
43.135 +
43.136 + private class DefaultDocumentListener implements DocumentListener {
43.137 +
43.138 + @Override
43.139 + public void insertUpdate(DocumentEvent e) {
43.140 + changeSupport.fireChange();
43.141 + }
43.142 +
43.143 + @Override
43.144 + public void removeUpdate(DocumentEvent e) {
43.145 + changeSupport.fireChange();
43.146 + }
43.147 +
43.148 + @Override
43.149 + public void changedUpdate(DocumentEvent e) {
43.150 + changeSupport.fireChange();
43.151 + }
43.152 + }
43.153 +
43.154 + /**
43.155 + * This method is called from within the constructor to initialize the form.
43.156 + * WARNING: Do NOT modify this code. The content of this method is always
43.157 + * regenerated by the Form Editor.
43.158 + */
43.159 + @SuppressWarnings("unchecked")
43.160 + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
43.161 + private void initComponents() {
43.162 +
43.163 + nameLabel = new javax.swing.JLabel();
43.164 + nameTextField = new javax.swing.JTextField();
43.165 + urlLabel = new javax.swing.JLabel();
43.166 + urlTextField = new javax.swing.JTextField();
43.167 + certDirectoryLabel = new javax.swing.JLabel();
43.168 + certTextField = new javax.swing.JTextField();
43.169 + browseButton = new javax.swing.JButton();
43.170 +
43.171 + org.openide.awt.Mnemonics.setLocalizedText(nameLabel, org.openide.util.NbBundle.getMessage(ConfigurationPanel.class, "ConfigurationPanel.nameLabel.text")); // NOI18N
43.172 +
43.173 + org.openide.awt.Mnemonics.setLocalizedText(urlLabel, org.openide.util.NbBundle.getMessage(ConfigurationPanel.class, "ConfigurationPanel.urlLabel.text")); // NOI18N
43.174 +
43.175 + org.openide.awt.Mnemonics.setLocalizedText(certDirectoryLabel, org.openide.util.NbBundle.getMessage(ConfigurationPanel.class, "ConfigurationPanel.certDirectoryLabel.text")); // NOI18N
43.176 +
43.177 + org.openide.awt.Mnemonics.setLocalizedText(browseButton, org.openide.util.NbBundle.getMessage(ConfigurationPanel.class, "ConfigurationPanel.browseButton.text")); // NOI18N
43.178 + browseButton.addActionListener(new java.awt.event.ActionListener() {
43.179 + public void actionPerformed(java.awt.event.ActionEvent evt) {
43.180 + browseButtonActionPerformed(evt);
43.181 + }
43.182 + });
43.183 +
43.184 + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
43.185 + this.setLayout(layout);
43.186 + layout.setHorizontalGroup(
43.187 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
43.188 + .addGroup(layout.createSequentialGroup()
43.189 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
43.190 + .addComponent(certDirectoryLabel)
43.191 + .addComponent(urlLabel)
43.192 + .addComponent(nameLabel))
43.193 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
43.194 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
43.195 + .addGroup(layout.createSequentialGroup()
43.196 + .addComponent(certTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 202, Short.MAX_VALUE)
43.197 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
43.198 + .addComponent(browseButton))
43.199 + .addComponent(nameTextField)
43.200 + .addComponent(urlTextField)))
43.201 + );
43.202 + layout.setVerticalGroup(
43.203 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
43.204 + .addGroup(layout.createSequentialGroup()
43.205 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
43.206 + .addComponent(nameLabel)
43.207 + .addComponent(nameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
43.208 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
43.209 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
43.210 + .addComponent(urlLabel)
43.211 + .addComponent(urlTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
43.212 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
43.213 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
43.214 + .addComponent(certDirectoryLabel)
43.215 + .addComponent(certTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
43.216 + .addComponent(browseButton)))
43.217 + );
43.218 + }// </editor-fold>//GEN-END:initComponents
43.219 +
43.220 + private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed
43.221 + JFileChooser chooser = new JFileChooser();
43.222 + chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
43.223 + chooser.setFileHidingEnabled(false);
43.224 + String text = UiUtils.getValue(certTextField);
43.225 + if (text != null) {
43.226 + chooser.setSelectedFile(new File(text));
43.227 + }
43.228 + if (chooser.showOpenDialog(SwingUtilities.getWindowAncestor(this)) == JFileChooser.APPROVE_OPTION) {
43.229 + certTextField.setText(chooser.getSelectedFile().getAbsolutePath());
43.230 + }
43.231 + }//GEN-LAST:event_browseButtonActionPerformed
43.232 +
43.233 +
43.234 + // Variables declaration - do not modify//GEN-BEGIN:variables
43.235 + private javax.swing.JButton browseButton;
43.236 + private javax.swing.JLabel certDirectoryLabel;
43.237 + private javax.swing.JTextField certTextField;
43.238 + private javax.swing.JLabel nameLabel;
43.239 + private javax.swing.JTextField nameTextField;
43.240 + private javax.swing.JLabel urlLabel;
43.241 + private javax.swing.JTextField urlTextField;
43.242 + // End of variables declaration//GEN-END:variables
43.243 +}
44.1 --- a/docker.ui/src/org/netbeans/modules/docker/ui/wizard/DockerConnectionPanel.java Wed Mar 23 21:02:01 2016 +0000
44.2 +++ b/docker.ui/src/org/netbeans/modules/docker/ui/wizard/DockerConnectionPanel.java Thu Mar 24 15:34:03 2016 +0100
44.3 @@ -44,24 +44,31 @@
44.4 import java.io.File;
44.5 import java.net.MalformedURLException;
44.6 import java.net.URL;
44.7 +import java.util.HashMap;
44.8 +import java.util.Map;
44.9 import java.util.regex.Matcher;
44.10 import java.util.regex.Pattern;
44.11 import javax.swing.event.ChangeEvent;
44.12 import javax.swing.event.ChangeListener;
44.13 +import org.netbeans.modules.docker.api.DockerAction;
44.14 import org.netbeans.modules.docker.api.DockerInstance;
44.15 -import org.netbeans.modules.docker.api.DockerIntegration;
44.16 +import org.netbeans.modules.docker.api.DockerSupport;
44.17 import org.openide.WizardDescriptor;
44.18 +import org.openide.WizardValidationException;
44.19 import org.openide.util.ChangeSupport;
44.20 import org.openide.util.HelpCtx;
44.21 import org.openide.util.NbBundle;
44.22 import org.openide.util.Utilities;
44.23
44.24 -public class DockerConnectionPanel implements WizardDescriptor.Panel<WizardDescriptor>, ChangeListener {
44.25 +@NbBundle.Messages("MSG_InaccessibleSocket=Socket is not accessible.")
44.26 +public class DockerConnectionPanel implements WizardDescriptor.ExtendedAsynchronousValidatingPanel<WizardDescriptor>, ChangeListener {
44.27
44.28 private static final Pattern REMOTE_HOST_PATTERN = Pattern.compile("^(tcp://)[^/:](:\\d+)($|/.*)"); // NOI18N
44.29
44.30 private final ChangeSupport changeSupport = new ChangeSupport(this);
44.31
44.32 + private final Map<String, Object> values = new HashMap<>();
44.33 +
44.34 /**
44.35 * The visual component that displays this panel. If you need to access the
44.36 * component from this class, just use getComponent().
44.37 @@ -94,6 +101,7 @@
44.38 @NbBundle.Messages({
44.39 "MSG_EmptyDisplayName=Display name must not be empty.",
44.40 "MSG_AlreadyUsedDisplayName=Display name is already used by another instance.",
44.41 + "MSG_EmptySocket=Unix socket must not be empty.",
44.42 "MSG_EmptyUrl=URL must not be empty.",
44.43 "MSG_InvalidUrl=URL must be valid http or https URL.",
44.44 "MSG_NonExistingCertificatePath=The certificates path does not exist.",
44.45 @@ -108,68 +116,145 @@
44.46 wizard.putProperty(WizardDescriptor.PROP_INFO_MESSAGE, null);
44.47 wizard.putProperty(WizardDescriptor.PROP_WARNING_MESSAGE, null);
44.48
44.49 - String displayName = component.getDisplayName();
44.50 + Configuration panel = component.getConfiguration();
44.51 + String displayName = panel.getDisplayName();
44.52 if (displayName == null) {
44.53 wizard.putProperty(WizardDescriptor.PROP_ERROR_MESSAGE, Bundle.MSG_EmptyDisplayName());
44.54 return false;
44.55 }
44.56 - for (DockerInstance instance : DockerIntegration.getDefault().getInstances()) {
44.57 + for (DockerInstance instance : DockerSupport.getDefault().getInstances()) {
44.58 if (displayName.equals(instance.getDisplayName())) {
44.59 wizard.putProperty(WizardDescriptor.PROP_ERROR_MESSAGE, Bundle.MSG_AlreadyUsedDisplayName());
44.60 return false;
44.61 }
44.62 }
44.63
44.64 - String url = component.getUrl();
44.65 - if (url == null) {
44.66 - wizard.putProperty(WizardDescriptor.PROP_ERROR_MESSAGE, Bundle.MSG_EmptyUrl());
44.67 - return false;
44.68 - }
44.69 + if (panel.isSocketSelected()) {
44.70 + File socket = panel.getSocket();
44.71 + if (socket == null) {
44.72 + wizard.putProperty(WizardDescriptor.PROP_ERROR_MESSAGE, Bundle.MSG_EmptySocket());
44.73 + return false;
44.74 + }
44.75 + if (!socket.exists() || !socket.canRead() || !socket.canWrite()) {
44.76 + wizard.putProperty(WizardDescriptor.PROP_ERROR_MESSAGE, Bundle.MSG_InaccessibleSocket());
44.77 + return false;
44.78 + }
44.79 + } else {
44.80 + String url = panel.getUrl();
44.81 + if (url == null) {
44.82 + wizard.putProperty(WizardDescriptor.PROP_ERROR_MESSAGE, Bundle.MSG_EmptyUrl());
44.83 + return false;
44.84 + }
44.85
44.86 - URL realUrl = null;
44.87 - boolean urlWrong = false;
44.88 - try {
44.89 - realUrl = new URL(url);
44.90 - if (!"http".equals(realUrl.getProtocol()) && !"https".equals(realUrl.getProtocol())) { // NOI18N
44.91 + URL realUrl = null;
44.92 + boolean urlWrong = false;
44.93 + try {
44.94 + realUrl = new URL(url);
44.95 + if (!"http".equals(realUrl.getProtocol()) // NOI18N
44.96 + && !"https".equals(realUrl.getProtocol())) { // NOI18N
44.97 + urlWrong = true;
44.98 + }
44.99 + } catch (MalformedURLException ex) {
44.100 urlWrong = true;
44.101 }
44.102 - } catch (MalformedURLException ex) {
44.103 - urlWrong = true;
44.104 - }
44.105 - if (urlWrong) {
44.106 - wizard.putProperty(WizardDescriptor.PROP_ERROR_MESSAGE, Bundle.MSG_InvalidUrl());
44.107 - return false;
44.108 - }
44.109 -
44.110 - String certPath = component.getCertPath();
44.111 - if (certPath != null) {
44.112 - File certPathFile = new File(certPath);
44.113 - if (!certPathFile.isDirectory()) {
44.114 - wizard.putProperty(WizardDescriptor.PROP_ERROR_MESSAGE, Bundle.MSG_NonExistingCertificatePath());
44.115 + if (urlWrong) {
44.116 + wizard.putProperty(WizardDescriptor.PROP_ERROR_MESSAGE, Bundle.MSG_InvalidUrl());
44.117 return false;
44.118 }
44.119 - if (!new File(certPathFile, AddDockerInstanceWizard.DEFAULT_CA_FILE).isFile()) {
44.120 - wizard.putProperty(WizardDescriptor.PROP_ERROR_MESSAGE,
44.121 - Bundle.MSG_CertificatePathMissingFile(AddDockerInstanceWizard.DEFAULT_CA_FILE));
44.122 - return false;
44.123 +
44.124 + String certPath = panel.getCertPath();
44.125 + if (certPath != null) {
44.126 + File certPathFile = new File(certPath);
44.127 + if (!certPathFile.isDirectory()) {
44.128 + wizard.putProperty(WizardDescriptor.PROP_ERROR_MESSAGE, Bundle.MSG_NonExistingCertificatePath());
44.129 + return false;
44.130 + }
44.131 + if (!new File(certPathFile, AddDockerInstanceWizard.DEFAULT_CA_FILE).isFile()) {
44.132 + wizard.putProperty(WizardDescriptor.PROP_ERROR_MESSAGE,
44.133 + Bundle.MSG_CertificatePathMissingFile(AddDockerInstanceWizard.DEFAULT_CA_FILE));
44.134 + return false;
44.135 + }
44.136 + if (!new File(certPathFile, AddDockerInstanceWizard.DEFAULT_CERT_FILE).isFile()) {
44.137 + wizard.putProperty(WizardDescriptor.PROP_ERROR_MESSAGE,
44.138 + Bundle.MSG_CertificatePathMissingFile(AddDockerInstanceWizard.DEFAULT_CERT_FILE));
44.139 + return false;
44.140 + }
44.141 + if (!new File(certPathFile, AddDockerInstanceWizard.DEFAULT_KEY_FILE).isFile()) {
44.142 + wizard.putProperty(WizardDescriptor.PROP_ERROR_MESSAGE,
44.143 + Bundle.MSG_CertificatePathMissingFile(AddDockerInstanceWizard.DEFAULT_KEY_FILE));
44.144 + return false;
44.145 + }
44.146 }
44.147 - if (!new File(certPathFile, AddDockerInstanceWizard.DEFAULT_CERT_FILE).isFile()) {
44.148 - wizard.putProperty(WizardDescriptor.PROP_ERROR_MESSAGE,
44.149 - Bundle.MSG_CertificatePathMissingFile(AddDockerInstanceWizard.DEFAULT_CERT_FILE));
44.150 - return false;
44.151 - }
44.152 - if (!new File(certPathFile, AddDockerInstanceWizard.DEFAULT_KEY_FILE).isFile()) {
44.153 - wizard.putProperty(WizardDescriptor.PROP_ERROR_MESSAGE,
44.154 - Bundle.MSG_CertificatePathMissingFile(AddDockerInstanceWizard.DEFAULT_KEY_FILE));
44.155 - return false;
44.156 +
44.157 + if (realUrl != null && "https".equals(realUrl.getProtocol()) && certPath == null) { // NOI18N
44.158 + wizard.putProperty(WizardDescriptor.PROP_WARNING_MESSAGE, Bundle.MSG_NoCertificatesForSecure());
44.159 }
44.160 }
44.161
44.162 - if (realUrl != null && "https".equals(realUrl.getProtocol()) && certPath == null) { // NOI18N
44.163 - wizard.putProperty(WizardDescriptor.PROP_WARNING_MESSAGE, Bundle.MSG_NoCertificatesForSecure());
44.164 + return true;
44.165 + }
44.166 +
44.167 + @Override
44.168 + public void prepareValidation() {
44.169 + synchronized (values) {
44.170 + values.clear();
44.171 + Configuration panel = component.getConfiguration();
44.172 + values.put(AddDockerInstanceWizard.DISPLAY_NAME_PROPERTY, panel.getDisplayName());
44.173 + values.put(AddDockerInstanceWizard.SOCKET_SELECTED_PROPERTY, panel.isSocketSelected());
44.174 + values.put(AddDockerInstanceWizard.SOCKET_PROPERTY, panel.getSocket());
44.175 + values.put(AddDockerInstanceWizard.URL_PROPERTY, panel.getUrl());
44.176 + values.put(AddDockerInstanceWizard.CERTIFICATE_PATH_PROPERTY, panel.getCertPath());
44.177 }
44.178 + component.setWaitingState(true);
44.179 + }
44.180
44.181 - return true;
44.182 + @Override
44.183 + public void finishValidation() {
44.184 + component.setWaitingState(false);
44.185 + }
44.186 +
44.187 + @NbBundle.Messages("MSG_CannotConnect=Cannot establish connection.")
44.188 + @Override
44.189 + public void validate() throws WizardValidationException {
44.190 + try {
44.191 + DockerInstance instance;
44.192 + synchronized (values) {
44.193 + boolean socketSelected = (Boolean) values.get(AddDockerInstanceWizard.SOCKET_SELECTED_PROPERTY);
44.194 + if (socketSelected) {
44.195 + File socket = (File) values.get(AddDockerInstanceWizard.SOCKET_PROPERTY);
44.196 + // this is repeated here as the acessibility might have change since the last check
44.197 + if (!socket.exists() || !socket.canRead() || !socket.canWrite()) {
44.198 + String error = Bundle.MSG_InaccessibleSocket();
44.199 + throw new WizardValidationException(component, error, error);
44.200 + }
44.201 + instance = DockerInstance.getInstance(Utilities.toURI(socket).toURL().toString(),
44.202 + null, null, null, null);
44.203 + } else {
44.204 + File caFile = null;
44.205 + File certFile = null;
44.206 + File keyFile = null;
44.207 +
44.208 + String strCertPath = (String) values.get(AddDockerInstanceWizard.CERTIFICATE_PATH_PROPERTY);
44.209 + if (strCertPath != null) {
44.210 + File file = new File(strCertPath);
44.211 + caFile = new File(file, AddDockerInstanceWizard.DEFAULT_CA_FILE);
44.212 + certFile = new File(file, AddDockerInstanceWizard.DEFAULT_CERT_FILE);
44.213 + keyFile = new File(file, AddDockerInstanceWizard.DEFAULT_KEY_FILE);
44.214 + }
44.215 + instance = DockerInstance.getInstance((String) values.get(AddDockerInstanceWizard.URL_PROPERTY),
44.216 + null, caFile, certFile, keyFile);
44.217 + }
44.218 + }
44.219 +
44.220 + DockerAction action = new DockerAction(instance);
44.221 + if (!action.ping()) {
44.222 + String error = Bundle.MSG_CannotConnect();
44.223 + throw new WizardValidationException(component, error, error);
44.224 + }
44.225 + } catch (MalformedURLException ex) {
44.226 + String error = Bundle.MSG_CannotConnect();
44.227 + throw new WizardValidationException(component, error, error);
44.228 + }
44.229 }
44.230
44.231 @Override
44.232 @@ -187,27 +272,42 @@
44.233 })
44.234 @Override
44.235 public void readSettings(WizardDescriptor wiz) {
44.236 + boolean init = false;
44.237 if (wizard == null) {
44.238 + init = true;
44.239 wizard = wiz;
44.240 }
44.241
44.242 + Configuration panel = component.getConfiguration();
44.243 String displayName = (String) wiz.getProperty(AddDockerInstanceWizard.DISPLAY_NAME_PROPERTY);
44.244 - if (displayName == null) {
44.245 + if (displayName == null && init) {
44.246 displayName = Bundle.LBL_DefaultDisplayName();
44.247 }
44.248 - component.setDisplayName(displayName);
44.249 + panel.setDisplayName(displayName);
44.250 +
44.251 + Boolean socketSelected = (Boolean) wiz.getProperty(AddDockerInstanceWizard.SOCKET_SELECTED_PROPERTY);
44.252 + if (socketSelected == null) {
44.253 + socketSelected = DockerSupport.getDefault().isSocketSupported();
44.254 + }
44.255 + panel.setSocketSelected(socketSelected);
44.256 +
44.257 + File socket = (File) wiz.getProperty(AddDockerInstanceWizard.SOCKET_PROPERTY);
44.258 + if (socket == null && init && socketSelected) {
44.259 + socket = getDefaultSocket();
44.260 + }
44.261 + panel.setSocket(socket);
44.262
44.263 String url = (String) wiz.getProperty(AddDockerInstanceWizard.URL_PROPERTY);
44.264 - if (url == null) {
44.265 + if (url == null && init && !socketSelected) {
44.266 url = getDefaultUrl();
44.267 }
44.268 - component.setUrl(url);
44.269 + panel.setUrl(url);
44.270
44.271 String certPath = (String) wiz.getProperty(AddDockerInstanceWizard.CERTIFICATE_PATH_PROPERTY);
44.272 - if (certPath == null) {
44.273 + if (certPath == null && init && !socketSelected) {
44.274 certPath = getDefaultCertificatePath();
44.275 }
44.276 - component.setCertPath(certPath);
44.277 + panel.setCertPath(certPath);
44.278
44.279 // XXX revalidate; is this bug?
44.280 changeSupport.fireChange();
44.281 @@ -215,9 +315,12 @@
44.282
44.283 @Override
44.284 public void storeSettings(WizardDescriptor wiz) {
44.285 - wiz.putProperty(AddDockerInstanceWizard.DISPLAY_NAME_PROPERTY, component.getDisplayName());
44.286 - wiz.putProperty(AddDockerInstanceWizard.URL_PROPERTY, component.getUrl());
44.287 - wiz.putProperty(AddDockerInstanceWizard.CERTIFICATE_PATH_PROPERTY, component.getCertPath());
44.288 + Configuration panel = component.getConfiguration();
44.289 + wiz.putProperty(AddDockerInstanceWizard.DISPLAY_NAME_PROPERTY, panel.getDisplayName());
44.290 + wiz.putProperty(AddDockerInstanceWizard.SOCKET_SELECTED_PROPERTY, panel.isSocketSelected());
44.291 + wiz.putProperty(AddDockerInstanceWizard.SOCKET_PROPERTY, panel.getSocket());
44.292 + wiz.putProperty(AddDockerInstanceWizard.URL_PROPERTY, panel.getUrl());
44.293 + wiz.putProperty(AddDockerInstanceWizard.CERTIFICATE_PATH_PROPERTY, panel.getCertPath());
44.294 }
44.295
44.296 @Override
44.297 @@ -225,6 +328,14 @@
44.298 changeSupport.fireChange();
44.299 }
44.300
44.301 + private static File getDefaultSocket() {
44.302 + File file = new File("/var/run/docker.sock"); // NOI18N
44.303 + if (file.exists()) {
44.304 + return file;
44.305 + }
44.306 + return null;
44.307 + }
44.308 +
44.309 private static String getDefaultUrl() {
44.310 String url = null;
44.311 String envUrl = System.getenv("DOCKER_HOST"); // NOI18N
45.1 --- a/docker.ui/src/org/netbeans/modules/docker/ui/wizard/DockerConnectionVisual.form Wed Mar 23 21:02:01 2016 +0000
45.2 +++ b/docker.ui/src/org/netbeans/modules/docker/ui/wizard/DockerConnectionVisual.form Thu Mar 24 15:34:03 2016 +0100
45.3 @@ -16,100 +16,51 @@
45.4 <Layout>
45.5 <DimensionLayout dim="0">
45.6 <Group type="103" groupAlignment="0" attributes="0">
45.7 - <Component id="explanationLabel" pref="0" max="32767" attributes="0"/>
45.8 - <Group type="102" alignment="0" attributes="0">
45.9 - <Group type="103" groupAlignment="0" attributes="0">
45.10 - <Component id="certDirectoryLabel" alignment="0" min="-2" max="-2" attributes="0"/>
45.11 - <Component id="urlLabel" alignment="0" min="-2" max="-2" attributes="0"/>
45.12 - <Component id="nameLabel" alignment="0" min="-2" max="-2" attributes="0"/>
45.13 - </Group>
45.14 - <EmptySpace max="-2" attributes="0"/>
45.15 - <Group type="103" groupAlignment="0" attributes="0">
45.16 - <Component id="nameTextField" max="32767" attributes="0"/>
45.17 - <Component id="urlTextField" pref="310" max="32767" attributes="0"/>
45.18 - <Group type="102" alignment="0" attributes="0">
45.19 - <Component id="certTextField" max="32767" attributes="0"/>
45.20 - <EmptySpace max="-2" attributes="0"/>
45.21 - <Component id="browseButton" min="-2" max="-2" attributes="0"/>
45.22 - </Group>
45.23 - </Group>
45.24 - </Group>
45.25 + <Component id="mainPanel" max="32767" attributes="0"/>
45.26 + <Component id="southPanel" alignment="1" max="32767" attributes="0"/>
45.27 </Group>
45.28 </DimensionLayout>
45.29 <DimensionLayout dim="1">
45.30 <Group type="103" groupAlignment="0" attributes="0">
45.31 <Group type="102" alignment="0" attributes="0">
45.32 - <Group type="103" groupAlignment="3" attributes="0">
45.33 - <Component id="nameLabel" alignment="3" min="-2" max="-2" attributes="0"/>
45.34 - <Component id="nameTextField" alignment="3" min="-2" max="-2" attributes="0"/>
45.35 - </Group>
45.36 - <EmptySpace max="-2" attributes="0"/>
45.37 - <Group type="103" groupAlignment="3" attributes="0">
45.38 - <Component id="urlLabel" alignment="3" min="-2" max="-2" attributes="0"/>
45.39 - <Component id="urlTextField" alignment="3" min="-2" max="-2" attributes="0"/>
45.40 - </Group>
45.41 - <EmptySpace max="-2" attributes="0"/>
45.42 - <Group type="103" groupAlignment="3" attributes="0">
45.43 - <Component id="certDirectoryLabel" alignment="3" min="-2" max="-2" attributes="0"/>
45.44 - <Component id="certTextField" alignment="3" min="-2" max="-2" attributes="0"/>
45.45 - <Component id="browseButton" alignment="3" min="-2" max="-2" attributes="0"/>
45.46 - </Group>
45.47 + <Component id="mainPanel" max="-2" attributes="0"/>
45.48 <EmptySpace type="unrelated" max="-2" attributes="0"/>
45.49 - <Component id="explanationLabel" min="-2" max="-2" attributes="0"/>
45.50 + <Component id="southPanel" max="32767" attributes="0"/>
45.51 </Group>
45.52 </Group>
45.53 </DimensionLayout>
45.54 </Layout>
45.55 <SubComponents>
45.56 - <Component class="javax.swing.JLabel" name="urlLabel">
45.57 - <Properties>
45.58 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
45.59 - <ComponentRef name="urlTextField"/>
45.60 - </Property>
45.61 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
45.62 - <ResourceString bundle="org/netbeans/modules/docker/ui/wizard/Bundle.properties" key="DockerConnectionVisual.urlLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
45.63 - </Property>
45.64 - </Properties>
45.65 - </Component>
45.66 - <Component class="javax.swing.JTextField" name="urlTextField">
45.67 - </Component>
45.68 - <Component class="javax.swing.JLabel" name="explanationLabel">
45.69 - <Properties>
45.70 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
45.71 - <ResourceString bundle="org/netbeans/modules/docker/ui/wizard/Bundle.properties" key="DockerConnectionVisual.explanationLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
45.72 - </Property>
45.73 - </Properties>
45.74 - </Component>
45.75 - <Component class="javax.swing.JLabel" name="nameLabel">
45.76 - <Properties>
45.77 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
45.78 - <ComponentRef name="nameTextField"/>
45.79 - </Property>
45.80 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
45.81 - <ResourceString bundle="org/netbeans/modules/docker/ui/wizard/Bundle.properties" key="DockerConnectionVisual.nameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
45.82 - </Property>
45.83 - </Properties>
45.84 - </Component>
45.85 - <Component class="javax.swing.JTextField" name="nameTextField">
45.86 - </Component>
45.87 - <Component class="javax.swing.JLabel" name="certDirectoryLabel">
45.88 - <Properties>
45.89 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
45.90 - <ResourceString bundle="org/netbeans/modules/docker/ui/wizard/Bundle.properties" key="DockerConnectionVisual.certDirectoryLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
45.91 - </Property>
45.92 - </Properties>
45.93 - </Component>
45.94 - <Component class="javax.swing.JTextField" name="certTextField">
45.95 - </Component>
45.96 - <Component class="javax.swing.JButton" name="browseButton">
45.97 - <Properties>
45.98 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
45.99 - <ResourceString bundle="org/netbeans/modules/docker/ui/wizard/Bundle.properties" key="DockerConnectionVisual.browseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
45.100 - </Property>
45.101 - </Properties>
45.102 - <Events>
45.103 - <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="browseButtonActionPerformed"/>
45.104 - </Events>
45.105 - </Component>
45.106 + <Container class="javax.swing.JPanel" name="mainPanel">
45.107 +
45.108 + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
45.109 + </Container>
45.110 + <Container class="javax.swing.JPanel" name="southPanel">
45.111 +
45.112 + <Layout>
45.113 + <DimensionLayout dim="0">
45.114 + <Group type="103" groupAlignment="0" attributes="0">
45.115 + <Group type="102" alignment="0" attributes="0">
45.116 + <Component id="testButton" min="-2" max="-2" attributes="0"/>
45.117 + <EmptySpace min="0" pref="291" max="32767" attributes="0"/>
45.118 + </Group>
45.119 + </Group>
45.120 + </DimensionLayout>
45.121 + <DimensionLayout dim="1">
45.122 + <Group type="103" groupAlignment="0" attributes="0">
45.123 + <Component id="testButton" min="-2" max="-2" attributes="0"/>
45.124 + </Group>
45.125 + </DimensionLayout>
45.126 + </Layout>
45.127 + <SubComponents>
45.128 + <Component class="javax.swing.JButton" name="testButton">
45.129 + <Properties>
45.130 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
45.131 + <ResourceString bundle="org/netbeans/modules/docker/ui/wizard/Bundle.properties" key="DockerConnectionVisual.testButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
45.132 + </Property>
45.133 + </Properties>
45.134 + </Component>
45.135 + </SubComponents>
45.136 + </Container>
45.137 </SubComponents>
45.138 </Form>
46.1 --- a/docker.ui/src/org/netbeans/modules/docker/ui/wizard/DockerConnectionVisual.java Wed Mar 23 21:02:01 2016 +0000
46.2 +++ b/docker.ui/src/org/netbeans/modules/docker/ui/wizard/DockerConnectionVisual.java Thu Mar 24 15:34:03 2016 +0100
46.3 @@ -41,40 +41,43 @@
46.4 */
46.5 package org.netbeans.modules.docker.ui.wizard;
46.6
46.7 -import java.io.File;
46.8 -import javax.swing.JFileChooser;
46.9 -import javax.swing.SwingUtilities;
46.10 +import java.awt.Component;
46.11 +import java.awt.Cursor;
46.12 +import javax.swing.JPanel;
46.13 +import javax.swing.event.ChangeEvent;
46.14 import javax.swing.event.ChangeListener;
46.15 -import javax.swing.event.DocumentEvent;
46.16 -import javax.swing.event.DocumentListener;
46.17 -import org.netbeans.modules.docker.ui.UiUtils;
46.18 +import org.netbeans.modules.docker.api.DockerSupport;
46.19 import org.openide.util.ChangeSupport;
46.20 import org.openide.util.NbBundle;
46.21 -import org.openide.util.Utilities;
46.22
46.23 /**
46.24 *
46.25 * @author Petr Hejl
46.26 */
46.27 -public class DockerConnectionVisual extends javax.swing.JPanel {
46.28 +public class DockerConnectionVisual extends javax.swing.JPanel implements ChangeListener {
46.29
46.30 private final ChangeSupport changeSupport = new ChangeSupport(this);
46.31
46.32 + private final Configuration configPanel;
46.33 +
46.34 /**
46.35 * Creates new form DockerWizardVisual
46.36 */
46.37 public DockerConnectionVisual() {
46.38 initComponents();
46.39
46.40 - // do not show the port binding explanation on mac and windows
46.41 - if (Utilities.isMac() || Utilities.isWindows()) {
46.42 - explanationLabel.setVisible(false);
46.43 + if (DockerSupport.getDefault().isSocketSupported()) {
46.44 + configPanel = new ConfigurationLinuxPanel();
46.45 + } else {
46.46 + configPanel = new ConfigurationPanel();
46.47 }
46.48
46.49 - DefaultDocumentListener listener = new DefaultDocumentListener();
46.50 - nameTextField.getDocument().addDocumentListener(listener);
46.51 - urlTextField.getDocument().addDocumentListener(listener);
46.52 - certTextField.getDocument().addDocumentListener(listener);
46.53 + configPanel.addChangeListener(this);
46.54 + mainPanel.add((JPanel) configPanel);
46.55 +
46.56 + // disable it - it is not implemented
46.57 + // do we really want it?
46.58 + testButton.setVisible(false);
46.59 }
46.60
46.61 public void addChangeListener(ChangeListener l) {
46.62 @@ -85,28 +88,20 @@
46.63 changeSupport.removeChangeListener(l);
46.64 }
46.65
46.66 - public String getDisplayName() {
46.67 - return UiUtils.getValue(nameTextField);
46.68 + @Override
46.69 + public void stateChanged(ChangeEvent e) {
46.70 + changeSupport.fireChange();
46.71 }
46.72
46.73 - public void setDisplayName(String displayName) {
46.74 - nameTextField.setText(displayName);
46.75 + public Configuration getConfiguration() {
46.76 + return configPanel;
46.77 }
46.78
46.79 - public String getUrl() {
46.80 - return UiUtils.getValue(urlTextField);
46.81 - }
46.82 -
46.83 - public void setUrl(String url) {
46.84 - urlTextField.setText(url);
46.85 - }
46.86 -
46.87 - public String getCertPath() {
46.88 - return UiUtils.getValue(certTextField);
46.89 - }
46.90 -
46.91 - public void setCertPath(String path) {
46.92 - certTextField.setText(path);
46.93 + public void setWaitingState(boolean wait) {
46.94 + Component rootPane = getRootPane();
46.95 + if (rootPane != null) {
46.96 + rootPane.setCursor(wait ? Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR) : null);
46.97 + }
46.98 }
46.99
46.100 @NbBundle.Messages("MSG_Connection=Connection")
46.101 @@ -115,24 +110,6 @@
46.102 return Bundle.MSG_Connection();
46.103 }
46.104
46.105 - private class DefaultDocumentListener implements DocumentListener {
46.106 -
46.107 - @Override
46.108 - public void insertUpdate(DocumentEvent e) {
46.109 - changeSupport.fireChange();
46.110 - }
46.111 -
46.112 - @Override
46.113 - public void removeUpdate(DocumentEvent e) {
46.114 - changeSupport.fireChange();
46.115 - }
46.116 -
46.117 - @Override
46.118 - public void changedUpdate(DocumentEvent e) {
46.119 - changeSupport.fireChange();
46.120 - }
46.121 - }
46.122 -
46.123 /**
46.124 * This method is called from within the constructor to initialize the form.
46.125 * WARNING: Do NOT modify this code. The content of this method is always
46.126 @@ -142,93 +119,47 @@
46.127 // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
46.128 private void initComponents() {
46.129
46.130 - urlLabel = new javax.swing.JLabel();
46.131 - urlTextField = new javax.swing.JTextField();
46.132 - explanationLabel = new javax.swing.JLabel();
46.133 - nameLabel = new javax.swing.JLabel();
46.134 - nameTextField = new javax.swing.JTextField();
46.135 - certDirectoryLabel = new javax.swing.JLabel();
46.136 - certTextField = new javax.swing.JTextField();
46.137 - browseButton = new javax.swing.JButton();
46.138 + mainPanel = new javax.swing.JPanel();
46.139 + southPanel = new javax.swing.JPanel();
46.140 + testButton = new javax.swing.JButton();
46.141
46.142 - urlLabel.setLabelFor(urlTextField);
46.143 - org.openide.awt.Mnemonics.setLocalizedText(urlLabel, org.openide.util.NbBundle.getMessage(DockerConnectionVisual.class, "DockerConnectionVisual.urlLabel.text")); // NOI18N
46.144 + mainPanel.setLayout(new java.awt.BorderLayout());
46.145
46.146 - org.openide.awt.Mnemonics.setLocalizedText(explanationLabel, org.openide.util.NbBundle.getMessage(DockerConnectionVisual.class, "DockerConnectionVisual.explanationLabel.text")); // NOI18N
46.147 + org.openide.awt.Mnemonics.setLocalizedText(testButton, org.openide.util.NbBundle.getMessage(DockerConnectionVisual.class, "DockerConnectionVisual.testButton.text")); // NOI18N
46.148
46.149 - nameLabel.setLabelFor(nameTextField);
46.150 - org.openide.awt.Mnemonics.setLocalizedText(nameLabel, org.openide.util.NbBundle.getMessage(DockerConnectionVisual.class, "DockerConnectionVisual.nameLabel.text")); // NOI18N
46.151 -
46.152 - org.openide.awt.Mnemonics.setLocalizedText(certDirectoryLabel, org.openide.util.NbBundle.getMessage(DockerConnectionVisual.class, "DockerConnectionVisual.certDirectoryLabel.text")); // NOI18N
46.153 -
46.154 - org.openide.awt.Mnemonics.setLocalizedText(browseButton, org.openide.util.NbBundle.getMessage(DockerConnectionVisual.class, "DockerConnectionVisual.browseButton.text")); // NOI18N
46.155 - browseButton.addActionListener(new java.awt.event.ActionListener() {
46.156 - public void actionPerformed(java.awt.event.ActionEvent evt) {
46.157 - browseButtonActionPerformed(evt);
46.158 - }
46.159 - });
46.160 + javax.swing.GroupLayout southPanelLayout = new javax.swing.GroupLayout(southPanel);
46.161 + southPanel.setLayout(southPanelLayout);
46.162 + southPanelLayout.setHorizontalGroup(
46.163 + southPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
46.164 + .addGroup(southPanelLayout.createSequentialGroup()
46.165 + .addComponent(testButton)
46.166 + .addGap(0, 291, Short.MAX_VALUE))
46.167 + );
46.168 + southPanelLayout.setVerticalGroup(
46.169 + southPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
46.170 + .addComponent(testButton)
46.171 + );
46.172
46.173 javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
46.174 this.setLayout(layout);
46.175 layout.setHorizontalGroup(
46.176 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
46.177 - .addComponent(explanationLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
46.178 - .addGroup(layout.createSequentialGroup()
46.179 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
46.180 - .addComponent(certDirectoryLabel)
46.181 - .addComponent(urlLabel)
46.182 - .addComponent(nameLabel))
46.183 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
46.184 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
46.185 - .addComponent(nameTextField)
46.186 - .addComponent(urlTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 310, Short.MAX_VALUE)
46.187 - .addGroup(layout.createSequentialGroup()
46.188 - .addComponent(certTextField)
46.189 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
46.190 - .addComponent(browseButton))))
46.191 + .addComponent(mainPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
46.192 + .addComponent(southPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
46.193 );
46.194 layout.setVerticalGroup(
46.195 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
46.196 .addGroup(layout.createSequentialGroup()
46.197 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
46.198 - .addComponent(nameLabel)
46.199 - .addComponent(nameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
46.200 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
46.201 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
46.202 - .addComponent(urlLabel)
46.203 - .addComponent(urlTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
46.204 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
46.205 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
46.206 - .addComponent(certDirectoryLabel)
46.207 - .addComponent(certTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
46.208 - .addComponent(browseButton))
46.209 + .addComponent(mainPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
46.210 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
46.211 - .addComponent(explanationLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
46.212 + .addComponent(southPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
46.213 );
46.214 }// </editor-fold>//GEN-END:initComponents
46.215
46.216 - private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed
46.217 - JFileChooser chooser = new JFileChooser();
46.218 - chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
46.219 - chooser.setFileHidingEnabled(false);
46.220 - String text = certTextField.getText();
46.221 - if (text != null && !text.trim().isEmpty()) {
46.222 - chooser.setSelectedFile(new File(text));
46.223 - }
46.224 - if (chooser.showOpenDialog(SwingUtilities.getWindowAncestor(this)) == JFileChooser.APPROVE_OPTION) {
46.225 - certTextField.setText(chooser.getSelectedFile().getAbsolutePath());
46.226 - }
46.227 - }//GEN-LAST:event_browseButtonActionPerformed
46.228 -
46.229
46.230 // Variables declaration - do not modify//GEN-BEGIN:variables
46.231 - private javax.swing.JButton browseButton;
46.232 - private javax.swing.JLabel certDirectoryLabel;
46.233 - private javax.swing.JTextField certTextField;
46.234 - private javax.swing.JLabel explanationLabel;
46.235 - private javax.swing.JLabel nameLabel;
46.236 - private javax.swing.JTextField nameTextField;
46.237 - private javax.swing.JLabel urlLabel;
46.238 - private javax.swing.JTextField urlTextField;
46.239 + private javax.swing.JPanel mainPanel;
46.240 + private javax.swing.JPanel southPanel;
46.241 + private javax.swing.JButton testButton;
46.242 // End of variables declaration//GEN-END:variables
46.243 }