You are on page 1of 78

WebDynpro for Java

Consuming XI Web Service in J ava WebDynpro application


Enable/Disable & Show/Hide UI Elements in Web Dynpro for J ava
Creating a simple Web Dynpro application using Simple Graphics
Creating Extended Value Selector (EVS) - Static and Dynamic in Web Dynpro for J ava
Dynamic Runtime Manipulation-Context & View layout
Displaying a Smart form as PDF in Enterprise portal using WebDynpro for J ava






















Consuming XI Web Service in Java WebDynpro application

Steps to configure the scenario:
Step1: Create a Synchronous Scenario (SOAP to RFC) and Generate WSDL in PI7.0
Step2: Import the WSDL in NWDS and Create Views in NWDS
Step3: Deploy the J ava Web Dynpro in J 2EE Engine.
Step4: Test the Scenario.
Steps in detail:
Step1: Create a Scenario SOAP to RFC and Generate WSDL in PI7.0
When we send a Customer Number as Request to RFC it has to fetch the Customer Details as
Response.
Configure SLD as per the requirement and Import the BAPI in IR: BAPI_CUSTOMER_GETDETAIL2
Create Data Types

Create Message Types:


Create Message Interface

Create Mappings for Request and Response


Create Interface Mapping

Save and Activate all the Objects in IR.

Now Log in to Integration Directory and Create a Configuration Scenario
Create Business Service and Create Communication Channels
Create a Communication Channel of type SOAP as Sender with QOS =BE

Create a Communication Channel of type RFC as Receiver

Create a Sender Agreement

Create a Receiver Agreement

Create a Receiver Determination

Create a Interface Determination

The below screenshot shows all the Objects under Configuration Scenario.

Now Define a Web service as shown in the Screenshot

Enter the below path by giving the host and port details
http://<Hostname>:<Port>/XISOAPAdapter/MessageServlet?channel=:BS_CDWS:CC_soap_sender

Now save the wsdl.


Step2: Import the WSDL in NWDS and Create Views in NWDS
Now got to the NWDS (Netweaver Developers Studio)
Create a new WebDynpro Project

Enter the Project Name for J avaWebDynpro and say Finish.

Now Create a Model

Select Import Web Service Model and Say Next

Enter the Model Name, Model Package and select the radio button of Local File System or URL and say
Next.

Import the WSDL file (Which was created in PI(XI))

Check the path of the Target Address by clicking on Logical Ports.

Create two Views called StartView and ResultView

Create outbound plug and Inbound plug by right clicking on View
For StartView:
Outbound plug: ToResultView
Inbound plug: FromResultView
Actions for StartView:

Layout for StartView:
Create a Layout for Start View
Click on the root element and say Apply Template

Now select Form and say Next.

Select the Attributes to bind to bind them to form elements

In the Editor Column select InputField

At last my Layout for StartView looks like

For ResultView:
Outbound plug: ToStartView
Inbound plug: FromStartView
Actions for ResultView:

Create a Layout for ResultView

Select the Attributes to bind to bind them to form elements

In the Editor Column select TextView

At last my Layout for StartView looks like

Check the Diagram View

.
In the Diagram View for a Component, Choose Component Controller right click and say Apply Template

Now select Service Controller and say Next

Now select the Model class for the Model binding and a method called
executeRequest_CDWS_MI_CDWS_MI will be generated.

Check the Context Elements you want to bind.

Using Data link connect the StartView and Component Controller and also do Context Mapping.
Later Using Data link Connect ResultView and Component Controller and also do Context Mapping.
Using Data link Connect Component Controller and Model (FujitsuModel) and also do Context Mapping..
After doing above steps the total Diagram View looks like in below screenshot.

Add few coding lines for method executeRequest_CDWS_MI_CDWS_MI( ) as follows
This coding lines are mandatory to communicate with XI(PI).We should mention the userid and password
for XI system.
public void executeRequest_CDWS_MI_CDWS_MI( )
{
//@@begin executeRequest_CDWS_MI_CDWS_MI()
wdCont ext . cur r ent Request _CDWS_MI _CDWS_MI El ement ( ) . model Obj ect ( ) . _set User ( " PI S
UPER" ) ;
wdCont ext . cur r ent Request _CDWS_MI _CDWS_MI El ement ( ) . model Obj ect ( ) . _set Passwor d(
" xxxxxxxx" ) ;
/ / $$begi n Ser vi ce Cont r ol l er ( - 1540004708)
I WDMessageManager manager = wdComponent API . get MessageManager ( ) ;
t r y
{


wdCont ext . cur r ent Request _CDWS_MI _CDWS_MI El ement ( ) . model Obj ect ( ) . execut e( ) ;
/ /
wdCont ext . nodeResponse( ) . i nval i dat e( ) ;
wdCont ext . nodeResul t ( ) . i nval i dat e( ) ;

}
Step3: Deploy the J ava Web Dynpro in J 2EE Engine.
Create an Application

After creating the Application Save the objects and say
Deploy New Archive and Run

Enter the SDM Password to deploy J avaWebDynpro in to J 2EE Engine.

Step 4: Test the Scenario
After Successful Deployment Enter the Customer Number and say GetDetails now the response from
RFC via XI (PI) will be found in next view.

Response from RFC via XI (PI)

Now check the Message Processing in SXMB_MONI of XI (PI).

Enable/Disable & Show/Hide UI Elements in Web Dynpro Java

Scenario: Enabling/Disabling and Showing/Hiding the UI elements during runtime (as shown below).

Step 1. Creating a Web dynpro project.
Navigation:
Open NWDS
Open Web Dynpro explorer.
File->New->Web Dynpro project
Give the name of the project as Enable_Disable_Show_Hide_UI_Elements.

Step 2. Creating a Web Dynpro Component.
Create a Web Dynpro component in a package.


Confirm by choosing finish.
Save the changes by clicking on save all metadata on the application tool bar.
Step 3. Creating Context Elements.
Edit the context of the view MainView.
Create the following attributes in the context of the view MainView:
First Name
Last Name
Date of Birth
Date of J oining
Enablekey
Showkey
Booleankey
Visibilitykey
Booleankey should be of Data Type Boolean, Visibilitykey of type UI Element data type Visible.


Confirm by choosing finish.
Select the context attribute and switch to the properties tab of it.



Choose Visibility property for visibility attribute as shown above.
Press OK to continue.
Save the changes by clicking on save all metadata on the application tool bar.
Step 4. Data Binding on the Main view
Choose the layout tab of the view MainView.
By right Clicking on RootUIElementContainer select Insert Child and Create two groups one for the
Enable/disable UIelements and the other for Show/Hide the UI Elements.
Create two Radio Buttons by Inserting Child in Each Group.
Each of The Group is separated by Bread Crumb.
Right Click on Group and click Apply template.
Choose form.


Choose DateofBirth, DateofJ oining, FirstName, LastName and Click next.

Confirm by choosing finish.
Finally the View Will be as shown below:

...
Step 5. Assigning Properties for the Input Fields of Main view in Property Tab
For Enable or Disable Fields group select the Input Fields and Make the following changes in the
Property tab.
For Input Fields in the enabled make it as Booleankey of the context attribute.
For Radio Buttons Enable and Disable in Property tab give keyToSelect as E & D Respectively and
Selected key as Enablekey of the Context Attribute.


For Enable Radio button, create an Event Enable on Select in Property tab.


For Disable Radio button, create an Event Disable on Select in Property tab.

For Show or Hide Group also make changes in the Property tab for all Input Fields make the Visible as
VisibilityKey of The context Tab.

For Show or Hide Radio Buttons Disable in Property tab give keyToSelect as S & H Respectively and
Selected key as Show of the Context Attribute.
For Show Radio button, create an Event Show on Select in Property tab.

For Hide Radio Button Create an Event Hide on Select in Property tab.

Step 6. Code for the onAction Methods like Enable, Disable, Show, and Hide.
In Implementation tab, write the following Code for both the Events Enable and Disable which are created
as methods.
In
Implementation tab Write a Piece of Code for both the Events Show and Hide which are created
as methods.

Save the changes by clicking on save all metadata on the application tool bar.
Step 7. Creating an application for the web dynpro project
Web dynpro explorer->Enable_Disable_Show_Hide_UI_Elements->web dynpro->Applications.
Right click on application and create a new application.

Step 8. Rebuild the project
Web dynpro explorer->Enable_Disable_Show_Hide_UI_Elements
Right click on Enable_Disable_Show_Hide_UI_Elements .
Choose rebuild project.

Step 9. Deploy and run the application
Web dynpro explorer-> Enable_Disable_Show_Hide_UI_Elements -->web dynpro->Applications -->
EDSH_Application.
Right click on Application and choose Deploy new archive and run.
You can see the output in the browser as shown below.
Default View of the Webpage, and when enable is clicked.

When Disabled and Hide is Clicked

When Enabled and Shown











Using Simple Graphics in a Web Dynpro application

Description:
Add a Simple Business Graphic to your Web Dynpro application
Go to NWDSCreate Web Dynpro Project (SimpleGraphics)

Right click on componentsCreate a Component (SimpleGraphicsV)


Open the SimpleGraphicsV. Right click on the RootUIElementContainer in the Outline pane and select
Insert Child. Select the element Type of BusinessGraphics. Give your Element the name Simple
Graphic


You can see it both in the Outline pane, and the Layout pane, both shown here.


Highlight SimpleGraphic element in your view. Then go to the Property view in the bottom right hand
pane. Ensure that the property chartType is set to columns.
Change the height property to 300
Change the width property to 500



You will see that Business graphic in your Views layout has been resized.

Right Click on the SimpleGraphic element in the Outline pane. In the menu select Insert
Category. Right Click on theSimpleGraphic element in the Outline pane. In the menu select Insert
Series .Add 2 other simple series to the
BusinessGraphics.



Set the Label properties of your Simple Series as follows

Go to the Context view of your View. Right Click on the Context node and in the menu select New
Value Node .In the popup give it the name SimpleGraphic .Click Finish.
Add 4 Value Attributes to the node SimpleGraphic in your context with the names:
Category, ValueOne,ValueTwo and ValueThree. Category should be of type stringValueOne,
ValueTwo, and ValueThree should be of type double



Select the Layout of the SimpleGraphicsView.
- In the Outline pane of the SimpleGraphicsView, highlight the SimpleGraphic node.
- In the Property view in the bottom right hand pane, set the seriesSource property.

- Click the button shown in the seriesSource This will show a popup window of your
Views context.
- In the context popup select the node SimpleGraphic, then click OK.

- The seriesSource property will then be set as shown.

Set the Category view elements description property to the context SimpleGraphic.Category
Set the SimpleSeries1 view elements value property to the contextSimpleGraphic.ValueOne.
Set the SimpleSeries2 view elements value property to the contextSimpleGraphic.ValueTwo.
Set the SimpleSeries3 view elements value property to contextSimpleGraphic.ValueThree.


Add the code to fill the data to view context
Go to implementation tab of SimplegraphicVAdd the code in wdDoinit() method

Right click on Application Select create application (simpleGraphicAppl) NextNextFinish.


Rightclick on SimpleGraphicsApplDeploy Archive and Run
The output as follows

Introduction to chart Designer to Business Graphics(Extension to first application)
Open the view SimpleGraphicsV.Go to the Layout of the view.In the Outline pane, right click on your
Business Graphic SimpleGraphic and in the menu select Start Chart Designer .

The Chart Designer will show up in the upper right hand pane for your Business Grahphic. It is shown in
the image below.

Edit the properties of your business graphics in chart designer.
Set the Title of your businessgraphic. J ust highlight theTitle element in the Overview pain. Then enter
your title in the Caption property. Set the Legend caption. Same process you did for the Title, but for
Legend.


Set the Border properties of the legend to have a solid black border. Set the Title and Unit caption
property under the Categoryaxis element. (Open up the node, you will see a Title element).


Set the Unit caption as Months. Do the same as above but for the first Value Axis node.
- Set the Value Axis Title Caption
- Set the Value Axis Unit Caption



Change the Background Color. Highlight the Background element in the Overview pane.
Under Area Properties you can set the color. Do not forget to save your Metadata.






Right click on SimplegrahicsApplDeploy Archive and
Run.
The output as follows:

Creating Extended Value Selector (EVS) - Static and Dynamic in Web
Dynpro for Java

Description:
Extended value selector (EVS) is a type of value-help where a dictionary simple type is bound to
an input filed.
During the runtime a table pops up which allows its entries to be sorted and filtered.
Extended value selector is used when the values exceed 30.
The following example explains about the steps to be followed in order to use the extended value
selector in web dynpro java.
Step 1. Creating a web dynpro project.
Navigation:
Open NWDS
Open web Dynpro explorer.
File->New->Web Dynpro project
Give the name of the project as Extended_Value_Selector
Step 2. Creating a simple type Object.
Navigation:
Web dynpro explorer->Extended_Value_Selector->Dictionaries->local dictionary->data types->simple
types.

Confirm by choosing finish.
Let the data type be string.
Choose the tab Enumeration.

Add value and text for the new element.
Confirm by choosing finish.
Populate the enumeration with some elements.

Save the changes by clicking on save all metadata on the application tool bar.
Step 3. Creating a web dynpro component.
Create a webdynpro component in the same package as that of the simple type.


Confirm by choosing finish.
Step 4. Creating context elements
Edit the context of the view EVS_ComponentView.
Create a value attribute Object in the context of the view EVS_ComponentView

Confirm by choosing finish.
Select the context attribute and switch to the properties tab of it.
Assign the dictionary simple type Object as type the attribute.

Press ok to continue.
Save the changes by clicking on save all metadata on the application tool bar.
Step 5. Applying template for the view
Choose the tab layout of the view EVS_ComponentView.
Create two groups one for the static approach and the other for the dynamic approach.
Apply template to the view.
Choose form.

Check the attribute Object.

Choose next.
Change the Editor property of the attribute to input field.

Confirm by choosing finish.
Create a new value attribute Object _Dynamic of type string for Dynamic approach in the context
of the view EVS_ComponentView

Confirm by choosing finish.
Apply template to group dynamic by selecting the context attribute Object_Dynamic.

... Save the changes by clicking on save all metadata on the application tool bar.
Choose next.
Change the Editor property of the attribute to input field.

Confirm by choosing finish.
Step 6. Code for populating the values dynamically
Select the implementation tab of the EVS_ComponentView.
Write the following code under the method wdDoInit();

Step 7. Creating an application for the web dynpro project
Navigation.
Web dynpro explorer->Extended_Value_Selector->web dynpro->Application.
Right click on application and create a new application.

Step 8. Rebuild the project
Navigation.
Web dynpro explorer->Extended_Value_Selector
Right click on Extended_Value_Selector.
Choose rebuild project.
Step 9. Deploy and run the application
Navigation
Web dynpro explorer->Extended_Value_Selector->web dynpro->application->EVSApplication.
Right click on EVS Application and choose Deploy new archive and run.
You can see the output in the browser as shown below.

A table pops up with the key and display texts once you click on the icon beside the input field.

We can Filter the values according to the starting letter.

We can also sort the key and texts using selected column as key.

Dynamic Runtime Manipulation-Context & View layout using Web
Dynpro for Java

Customer-Business Case
There might be some scenarios where in we need to dynamically add nodes, their attributes to the view
controller context. In this case the View Layout needs to be defined dynamically using the above context
nodes and the attributes.
Following is the solution for the same:
Project name: DynamicUIManip
Package com.sap.training
Window name: MainWindow
View Name: Dynamic View
Click on Finish:
Path->NWDS->File->New->WebDynPro Project



Since everything in this component will be created dynamically at runtime, both the view context and the view
layout will remain empty.

View Context :

We can find here the context is empty. The context will be creating dynamically at runtime.
Part 1: Creating View Context Dynamically
Implementation In View Controller
publ i c voi d wdDoI ni t ( )
{
/ / @@begi n wdDoI ni t ( )
I WDNodeI nf o r oot NodeI nf o = wdCont ext . get NodeI nf o( ) ;
I WDNodeI nf o soNodeI nf o = r oot NodeI nf o. addChi l d(

" Sal esOr der s" , nul l , t r ue, f al se, t r ue, f al se, t r ue, t r ue, nul l , nul l , nul l ) ;
soNodeI nf o. addAt t r i but e( " Or der No" , " ddi c: com. sap. di ct i onar y. i nt eger " ) ;
soNodeI nf o. addAt t r i but e( " Sal esDat e" , " ddi c: com. sap. di ct i onar y. dat e" ) ;
soNodeI nf o. addAt t r i but e( " Sal esRep" , " ddi c: com. sap. di ct i onar y. st r i ng" ) ;
soNodeI nf o. addAt t r i but e( " LongText " , " ddi c: com. sap. di ct i onar y. st r i ng" ) ;

I WDNode soNode = wdCont ext . get Chi l dNode( " Sal esOr der s" , 0) ;
I WDNodeEl ement soEl ement = soNode. cr eat eEl ement ( ) ;
soEl ement . set At t r i but eVal ue( " Or der No" , new I nt eger ( 10) ) ;
soEl ement . set At t r i but eVal ue( " Sal esDat e" , new
Dat e( Syst em. cur r ent Ti meMi l l i s( ) ) ) ;
soEl ement . set At t r i but eVal ue( " Sal esRep" , " Si mpson" ) ;
soEl ement . set At t r i but eVal ue( " LongText " , " Pr i nt er Suppl i es" ) ;

soNode. addEl ement ( soEl ement ) ;


/ / @@end
}
Now t he Node Sal esOr der I S cr eat ed wi t h t he f ol l owi ng At t r i but es:
Sal esOr der ( node)
Or der No : ddi c: com. sap. di ct i onar y. i nt eger
Sal esDat e: ddi c: com. sap. di ct i onar y. dat e
Sal esRep: ddi c: com. sap. di ct i onar y. st r i ng
LongText : ddi c: com. sap. di ct i onar y. st r i ng
Part 2: Creating View Layout Dynamically
For t he above Cr eat ed Dynami c Cont ext we ar goi ng t o cr eat e Vi ew l ayout .
Locat e The met hod WDDOModf i f y vi ew
publ i c st at i c voi d wdDoModi f yVi ew( I Pr i vat eMai nVi ew wdThi s,
I Pr i vat eMai nVi ew. I Cont ext Node
wdCont ext , com. sap. t c. webdynpr o. pr ogmodel . api . I WDVi ew vi ew, bool ean f i r st Ti me)
{
/ / @@begi n wdDoModi f yVi ew

i f ( f i r st Ti me) {
I WDTr anspar ent Cont ai ner r oot El ement =
( I WDTr anspar ent Cont ai ner ) vi ew. get Root El ement ( ) ;

r oot El ement . cr eat eLayout ( I WDMat r i xLayout . cl ass) ;
I WDNodeI nf o soNodeI nf o =
wdCont ext . get Chi l dNode( " Sal esOr der s" , 0) . get NodeI nf o( ) ;

f or ( I t er at or i t er = soNodeI nf o. i t er at eAt t r i but es( ) ;
i t er . hasNext ( ) ; ) {

I WDAt t r i but eI nf o soAt t r I nf o =
( I WDAt t r i but eI nf o) i t er . next ( ) ;
I WDLabel l abel =( I WDLabel ) vi ew. cr eat eEl ement (
I WDLabel . cl ass,
soAt t r I nf o. get Name( ) + " Label " ) ;

l abel . set Text ( soAt t r I nf o. get Name( ) ) ;
l abel . cr eat eLayout Dat a( I WDMat r i xHeadDat a. cl ass) ;
l abel . set Desi gn( WDLabel Desi gn. LI GHT) ;
l abel . set Label For ( soAt t r I nf o. get Name( ) + " I nput " ) ;

r oot El ement . addChi l d( l abel ) ;

I WDI nput Fi el d i oFi el d =
( I WDI nput Fi el d) vi ew. cr eat eEl ement (
I WDI nput Fi el d. cl ass,
soAt t r I nf o. get Name( ) + " I nput " ) ;

i oFi el d. cr eat eLayout Dat a( I WDMat r i xDat a. cl ass) ;
i oFi el d. bi ndVal ue( soAt t r I nf o) ;
r oot El ement . addChi l d( i oFi el d) ;
}
/ / @@end
}

Part3- Creating Application and Testing
Create web Dynpro Application: DynamicManipAppl

Enter The name Of Application

Click on Next

Click on Next

Click on Finish
Build The Project

Create Archive

Deploy New Archive And Run

Output :

DisplayingaSmartformasPDFinEnterpriseportalusingWebDynproforJava

I have seen many questions on how a smart form should be displayed in portal. To answer this
question a person should have both Portal and ABAP knowledge. By giving this basic
information I want to make sure that displaying a smart form as PDF is a simple task.
Let me start from R/3 side
Create a smart form. Here I have created a simple smart form which displays Welcome to SAP
Smart forms.

Now create a function module with the following export parameter:

Place the following code in the function module
data :
lv_fnam type RS38L_FNAM,
gs_control TYPE ssfctrlop,
gs_output_options TYPE ssfcompop,
gs_otfdata TYPE itcoo,
gs_job_output_info TYPE ssfcrescl,
gt_otfdata TYPE STANDARD TABLE OF itcoo INITIAL SIZE 0.
CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME'
EXPORTING
formname ='YNAG_TEST_PDF'
IMPORTING
FM_NAME =lv_fnam
EXCEPTIONS
NO_FORM =1
NO_FUNCTION_MODULE =2
OTHERS =3 .
IF sy-subrc <>0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
CLEAR gs_job_output_info.
CLEAR gs_job_output_info-otfdata.
MOVE :
'X' TO gs_control-no_dialog,
'X' TO gs_control-getotf,
'LOCL'(047) TO GS_OUTPUT_OPTIONS-TDDEST.
CALL FUNCTION lv_fnam
EXPORTING
CONTROL_PARAMETERS =gs_control
OUTPUT_OPTIONS =gs_output_options
USER_SETTINGS =space
IMPORTING
J OB_OUTPUT_INFO =gs_job_output_info
EXCEPTIONS
FORMATTING_ERROR =1
INTERNAL_ERROR =2
SEND_ERROR =3
USER_CANCELED =4
OTHERS =5 .
IF sy-subrc <>0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
*Populate OTF data table
LOOP AT gs_job_output_info-otfdata INTO gs_otfdata.
APPEND gs_otfdata TO gt_otfdata.
CLEAR gs_otfdata.
ENDLOOP. " LOOP AT t_outtab-otfdata
DATA: lv_bytes TYPE p,
lv_bin_file type xstring,
gt_pdfdata TYPE STANDARD TABLE
OF tline
INITIAL SIZE 0.
* Convert OTF into PDF
CALL FUNCTION 'CONVERT_OTF'
EXPORTING
format ='PDF'
max_linewidth =255
IMPORTING
bin_filesize =lv_bytes
BIN_FILE =bin_file
TABLES
otf =gt_otfdata
lines =gt_pdfdata
EXCEPTIONS
err_max_linewidth =1
err_format =2
err_conv_not_possible =3
OTHERS =4.
Make sure that the function module is marked remote enabled.

With this we are done on the R/3 side.

In NWDS (Net Weaver Developer Studio) create an Adaptive RFC model which points
to the FM created in R/3.

Give model name



Now create an application to display the PDF

Insert a frame inside the view


Internal is a value node and url is value attribute of type string.
Place the following code in Init method
public void wdDoInit()
{
//@@begin wdDoInit()
Ynag_Test_Pdf_1_Input input =new Ynag_Test_Pdf_Input();
wdContext.nodeYnag_Test_Pdf_Input().bind(input);
try {
wdContext.currentYnag_Test_Pdf_InputElement().modelObject().execute();
}catch (WDDynamicRFCExecuteException e) {
e.printStackTrace();
wdContext.currentContextElement().setSdfgdsfsd(e.getMessage());
}
wdContext.currentInternalElement().setUrl(convertXStringToUrl(wdContext.currentOutputElement
().getBin_File()));
//@@end
}
//@@begin others
public String convertXStringToUrl(byte[] doc_content){
String url ="";
WDWebResourceType webResType =WDWebResourceType.PDF;
IWDWebResource webResource = WDWebResource.getWebResource(doc_content,
webResType);
try {
url =webResource.getURL();
}catch (WDURLException e) {
e.printStackTrace();
}
return url;
}
//@@end

If you are using single sign on make sure to enable User authentication in the application parameters.
User details are required for this as it is using Single sign on to connect to R/3.
In this case we have hard coded the Smart form to be used.
If you want it in dynamic way FM interfaces need to be changed accordingly.

You might also like